SQLAlchemy:提交后对象映射丢失了吗?

时间:2009-06-23 15:13:01

标签: python database sqlalchemy

我在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”中添加一个标志,这是表中的一个布尔字段,用于标记已处理的元素,但我希望这不是必需的。

如何让我的上述代码正常工作?

映入眼帘,

汤姆

3 个答案:

答案 0 :(得分: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()的作用,请参阅Using the Session

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

commit()始终首先发出flush()

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

答案 1 :(得分:2)

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

答案 2 :(得分:1)

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