我是SQLAlchemy的新手,并且在没有访问原始作者的情况下继承了一些有点混乱的代码库。
代码是通过调用DBSession.flush()
来编写的,似乎是作者想要确保数据被保存的任何时候。起初我只是遵循我在这段代码中看到的模式,但是当我正在阅读文档时,似乎这是不必要的 - 自动清理应该到位。另外,我遇到了一些AJAX调用的情况,这些调用会产生错误“InvalidRequestError:Session已经刷新”。
在什么情况下,我合法地想要保持对flush()的调用?
这是一个Pyramid应用程序,SQLAlchemy正在设置:
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension(), expire_on_commit=False))
Base = declarative_base()
答案 0 :(得分:26)
ZopeTransactionExtension
上的DBSession
与您项目中处于活动状态的pyramid_tm
一起将处理所有提交。您需要刷新的情况是:
您想要创建一个新对象并取回主键。
DBSession.add(obj)
DBSession.flush()
log.info('look, my new object got primary key %d', obj.id)
您希望尝试在保存点中执行某些SQL并在其失败时回滚而不会使整个事务无效。
sp = transaction.savepoint()
try:
foo = Foo()
foo.id = 5
DBSession.add(foo)
DBSession.flush()
except IntegrityError:
log.error('something already has id 5!!')
sp.rollback()
在涉及ORM的所有其他情况下,交易将在例外情况下中止,或由pyramid_tm
自动成功提交。如果您执行原始SQL,则需要自己执行transaction.commit()
或通过zope.sqlalchemy.mark_changed(DBSession)
将会话标记为脏,否则中兴通讯无法知道会话已更改。
除非您有充分的理由,否则您应将expire_on_commit
保留为True
的默认值。