我在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”中添加一个标志,这是表中的一个布尔字段,用于标记已处理的元素,但我希望这不是必需的。
如何让我的上述代码正常工作?
映入眼帘,
汤姆
答案 0 :(得分:3)
有几件事:
transaction
绑定的内容吗?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)。所以我怀疑这可能是你的模特有问题,所以也许你也可以发布它们?