问题: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
是None
我尝试的时候。我怎样才能使它工作?
回答 0
您的示例代码应该已经按原样工作。SQLAlchemy应该为其提供一个值f.id
,并假设其为自动生成的主键列。主键属性在flush()
生成时立即在过程中填充,并且不需要调用commit()
。因此,这里的答案在于以下一项或多项:
- 映射的详细信息
- 如果使用的后端有任何奇怪现象(例如,SQLite不会为复合主键生成整数值)
- 打开echo时发出的SQL表示什么
回答 1
我遇到了同样的问题,经过测试,我发现这些答案中没有一个是足够的。
当前,或者从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.
就是这样。
回答 2
谢谢大家 我通过修改列映射解决了我的问题。对我来说,autoincrement=True
是必需的。
起源:
id = Column('ID', Integer, primary_key=True, nullable=False)
修改后:
id = Column('ID', Integer, primary_key=True, autoincrement=True, nullable=True)
然后
session.flush()
print(f.id)
没关系!
回答 3
与dpb给出的答案不同,不需要刷新。刷新后,您可以访问id字段,sqlalchemy会自动刷新在后端自动生成的id
我遇到了这个问题,经过一番调查后找出了确切的原因,我的模型是用id作为integerfield创建的,而在我的表单中,id用hiddenfield表示(因为我不想在表单中显示id)。默认情况下,隐藏字段表示为文本。一旦我使用widget = hiddenInput()将表单更改为integerfield,问题就解决了。
回答 4
我曾经0
在调用session.add
方法之前分配给ID时遇到问题。该ID已由数据库正确分配,但在之后的会话中未检索到正确的ID session.flush()
。
回答 5
您应该尝试使用session.save_or_update(f)
而不是session.add(f)
。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。