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

2024-06-02 14:45:05 发布

您现在位置:Python中文网/ 问答频道 /正文

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

代码是通过调用DBSession.flush()来编写的,似乎是作者希望确保数据被保存的任何时候。一开始我只是在遵循我在代码中看到的模式,但是当我阅读文档时,这似乎是不必要的——应该设置自动刷新。此外,我还遇到了一些AJAX调用的情况,这些调用会生成错误“invalidriquesterror:Session is already flushing”。

在什么情况下,我可以合法地保持对flush()的调用?

这是一个金字塔应用程序,SQLAlchemy正在设置:

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

Tags: 数据代码文档sqlalchemyissession错误模式
1条回答
网友
1楼 · 发布于 2024-06-02 14:45:05

DBSession上的ZopeTransactionExtension与项目上处于活动状态的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

相关问题 更多 >