2

我在 SQLAlchemy 中遇到了一个简单的问题。我的表中有一个模型,我们在这里称它为 Model1。我想在这个表中添加一行,并获取自动增量键,所以我可以用它创建另一个模型,并使用这个键。这不是一个有缺陷的数据库设计(1:1 关系等)。我只需要另一个表中的这个密钥,因为另一个表正在传输到远程主机,我需要匹配的密钥,以便服务器能够相互理解。这两个表之间不会有进一步的本地引用,因此也无法创建关系。

考虑以下代码:

object1 = model.Model1(param)
DBSession.add(object1)

# if I do this, the line below fails with an UnboundExecutionError.
# and if I dont do this, object1.id won't be set yet
#transaction.commit()

object2 = model.AnotherModel(object1.id) #id holds the primary, autoincremented key

我希望我什至不必“手动”提交。基本上我想要实现的是,“Model1”不断增长,随着 Model.id 主键的增加。AnotherModel 始终只是尚未处理的 Model1 的一小部分。当然,我可以在“Model1”中添加一个标志,这是表中的一个布尔字段来标记已处理的元素,但我希望这不是必需的。

我怎样才能让我上面的代码工作?

问候,

汤姆

4

3 回答 3

3

有几件事:

  • 你能解释一下变量transaction绑定到什么吗?
  • 究竟是什么语句引发了 UnboundExecutionError?
  • 请提供完整的异常消息,包括堆栈跟踪。
  • 在这种情况下,“正常”的做法是调用DBSession.flush(). 你试过吗?

例子:

object1 = Model1(param)
DBSession.add(object1)
DBSession.flush()
assert object1.id != None # flushing the session populates the id

object2 = AnotherModel(object1.id)

有关 SA 会话及其flush()作用的详细说明,请参阅使用会话

基本上,flush()导致 Pending 实例变为 Persistent - 意味着新对象被插入到数据库表中。flush()还使用会话跟踪的具有更改的实例的值更新表。

commit()总是flush()先出问题。

在一个事务中,您可以多次刷新。每个 flush() 都会导致数据库中的 UPDATE 和/或 INSERT。可以提交或回滚整个事务。

于 2009-06-23T21:24:34.307 回答
2

如果您想在不提交任何内容的情况下生成新的主键标识符,只需调用 session.flush()。这将在当前事务中将所有待处理的内容发送到数据库。

于 2009-06-25T01:29:33.067 回答
1

我只将它与 ForeignKeys 一起使用,所以在第二种情况下你宁愿做 model.AnotherModel(model1=object1),然后它就可以工作了 (tm)。所以我怀疑这可能是你的模型的问题,所以也许你也可以发布它们?

于 2009-06-23T19:20:17.367 回答