问题:我应该什么时候在 SQLAlchemy 上调用 flush()?

我是 SQLAlchemy 的新手,并且在没有访问原作者的情况下继承了一个有点混乱的代码库。

代码中包含对DBSession.flush()的调用,似乎任何时候作者都想确保数据被保存。起初我只是按照我在这段代码中看到的模式,但是当我阅读文档时,似乎这是不必要的——自动刷新应该到位。此外,我遇到了一些 AJAX 调用的情况,这些调用会生成错误“InvalidRequestError: Session is already flushing”。

在什么情况下我会合法地继续调用flush()?

这是一个 Pyramid 应用程序,正在设置 SQLAlchemy:

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension(), expire_on_commit=False))
Base = declarative_base()

解答

DBSession上的ZopeTransactionExtension连同在您的项目中处于活动状态的pyramid_tm将为您处理所有提交。您需要冲洗的情况是:

  • 你想创建一个新对象并取回主键。
DBSession.add(obj)
DBSession.flush()
log.info('看,我的新对象有主键 %d', obj.id)
  • 您想尝试在保存点中执行一些 SQL,如果失败则回滚而不使整个事务无效。
sp u003d 事务.保存点()
尝试:
富u003d富()
foo.id u003d 5
DBSession.add(foo)
DBSession.flush()
除了 IntegrityError:
log.error('东西已经有 id 5!!')
sp.rollback()

在所有其他涉及 ORM 的情况下,事务将在异常时为您中止,或在成功时由pyramid_tm自动提交。如果执行原始 SQL,则需要自己执行transaction.commit()或通过zope.sqlalchemy.mark_changed(DBSession)将会话标记为脏,否则中兴通讯无法知道会话已更改。

此外,除非您有充分的理由,否则您应该将expire_on_commit保留为默认值True

Logo

Python社区为您提供最前沿的新闻资讯和知识内容

更多推荐