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

+2

你可以用'echo = True'初始化SA引擎,看看什么SQL在flush-time被执行?你所描述的*应该*工作,并给你的身份证,但可能会有一些其他问题导致f.id为无。 – 2009-08-23 00:07:20

您的示例代码应该照原样运行。假设它是一个自动生成的主键列,Sqlalchemy应该为f.id提供一个值。主键属性在生成时立即在flush()过程中被填充,并且不需要调用commit()。所以这里的答案在于你的映射的细节,如果后端有任何奇怪的怪癖(例如,SQLite不会为复合主键生成整数值)和/或当你发出SQL时说什么打开回声。

+0

你是对的,在shell中快速检查显示它用值填充主键字段。我将不得不调查为什么它在实践中不起作用。 – Eloff 2009-08-25 06:22:05

+2

“你的示例代码应该提供一个值”听起来像你说的“你本应该为id提供一个值”,而不是“你应该使用的代码应该保持原样”。我很清楚,你的意思是后者,而不是在三读之后。你能澄清吗? – stochastic 2017-01-08 18:44:39

你应该尝试使用session.save_or_update(f)代替session.add(f)

+1

'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. 

这是如何做到这一点。

+6

这越来越接近可能适用于我的答案,但我收到以下错误:InvalidRequestError:无法刷新实例'<....>'。在刷新后出现实例不再存在。欣赏任何见解。 – PlaidFan 2011-12-21 04:46:40

+1

你刚刚救了我的屁股。我不认为我会再次使用来自Django的ORM。 flush()命令不能像记录的IMHO一样工作。 – 2016-05-08 21:20:29

+1

更新,我不得不使用'''sessionmaker(autoflush = True)'',组合w/refresh()为我提供了行ID。 #grrr – 2016-05-08 21:33:13

不同于由dpb给出的答案,刷新不是必需的。 一旦你冲洗,你可以访问id字段,SQLAlchemy的自动刷新它自动在后台生成

我遇到了这个问题,并想出经过一番调查确切的原因,我的模型与ID创建为integerfield和ID在我的表单中,id用hiddenfield表示(因为我不想在表单中显示id)。隐藏字段默认表示为文本。一旦我用widget = hiddenInput()将表单更改为整数字段),问题就解决了。

+1

如前所述,只有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。