sqlalchemy flush()并获取插入的ID?
我想要做这样的事情:sqlalchemy flush()并获取插入的ID?
f = Foo(bar='x')
session.add(f)
session.flush()
# do additional queries using f.id before commit()
print f.id # should be not None
session.commit()
但f.id是无当我尝试它。我怎样才能使这个工作?
-Dan
您的示例代码应该照原样运行。假设它是一个自动生成的主键列,Sqlalchemy应该为f.id
提供一个值。主键属性在生成时立即在flush()过程中被填充,并且不需要调用commit()。所以这里的答案在于你的映射的细节,如果后端有任何奇怪的怪癖(例如,SQLite不会为复合主键生成整数值)和/或当你发出SQL时说什么打开回声。
你是对的,在shell中快速检查显示它用值填充主键字段。我将不得不调查为什么它在实践中不起作用。 – Eloff 2009-08-25 06:22:05
“你的示例代码应该提供一个值”听起来像你说的“你本应该为id提供一个值”,而不是“你应该使用的代码应该保持原样”。我很清楚,你的意思是后者,而不是在三读之后。你能澄清吗? – stochastic 2017-01-08 18:44:39
你应该尝试使用session.save_or_update(f)
代替session.add(f)
。
'save_or_update'自0.5左右开始不再使用。 'session.add()'应该这样做。 – 2009-08-23 00:10:47
我刚才遇到同样的问题,经过测试,我发现没有任何这些答案是足够的。
目前,或SQLAlchemy的.6+的,有一个非常简单的解决方案(我不知道这是否存在于以前的版本,虽然我想象它):
session.refresh()
因此,您的代码会是这个样子:
f = Foo(bar=x)
session.add(f)
session.flush()
# At this point, the object f has been pushed to the DB,
# and has been automatically assigned a unique primary key id
f.id
# is None
session.refresh(f)
# refresh updates given object in the session with its state in the DB
# (and can also only refresh certain attributes - search for documentation)
f.id
# is the automatically assigned primary key ID given in the database.
这是如何做到这一点。
这越来越接近可能适用于我的答案,但我收到以下错误:InvalidRequestError:无法刷新实例'<....>'。在刷新后出现实例不再存在。欣赏任何见解。 – PlaidFan 2011-12-21 04:46:40
你刚刚救了我的屁股。我不认为我会再次使用来自Django的ORM。 flush()命令不能像记录的IMHO一样工作。 – 2016-05-08 21:20:29
更新,我不得不使用'''sessionmaker(autoflush = True)'',组合w/refresh()为我提供了行ID。 #grrr – 2016-05-08 21:33:13
不同于由dpb给出的答案,刷新不是必需的。 一旦你冲洗,你可以访问id字段,SQLAlchemy的自动刷新它自动在后台生成
我遇到了这个问题,并想出经过一番调查确切的原因,我的模型与ID创建为integerfield和ID在我的表单中,id用hiddenfield表示(因为我不想在表单中显示id)。隐藏字段默认表示为文本。一旦我用widget = hiddenInput()将表单更改为整数字段),问题就解决了。
如前所述,只有refresh()对我有用。在进行数据迁移时,我需要循环中的行ID来填充FK。我试过每一个提交,刷新,会话黑客和刷新()的组合是唯一有效的工作。我的数据超级干净,我只是发现SQLA并不是那么好(在至少5个主要的ORMS中有相当大的exp)。试着获取add() - > commit()/ flush()的行标识,只需要5+小时的包装。 – 2016-05-08 21:25:08
我曾经在调用session.add
方法之前将0
分配给了ID,但有一个问题。该ID由数据库正确分配,但在session.flush()
后没有从会话中检索到正确的ID。
你可以用'echo = True'初始化SA引擎,看看什么SQL在flush-time被执行?你所描述的*应该*工作,并给你的身份证,但可能会有一些其他问题导致f.id为无。 – 2009-08-23 00:07:20