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

blo*_*cks 18 python sqlalchemy pyramid

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

代码是通过调用来编写的DBSession.flush(),似乎是作者想要确保数据被保存的任何时候.起初我只是遵循我在这段代码中看到的模式,但是当我正在阅读文档时,似乎这是不必要的 - 自动清理应该到位.另外,我遇​​到了一些AJAX调用的情况,这些调用会产生错误"InvalidRequestError:Session已经刷新".

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

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

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension(), expire_on_commit=False))
Base = declarative_base()
Run Code Online (Sandbox Code Playgroud)

Mic*_*kel 27

ZopeTransactionExtensionDBSession与结合pyramid_tm您的项目将处理所有提交你活跃.您需要刷新的情况是:

  • 您想要创建一个新对象并返回主键.

    DBSession.add(obj)
    DBSession.flush()
    log.info('look, my new object got primary key %d', obj.id)
    
    Run Code Online (Sandbox Code Playgroud)
  • 您希望尝试在保存点中执行某些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()
    
    Run Code Online (Sandbox Code Playgroud)

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

除非你有充分的理由expire_on_commit,True否则你应该默认离开.

  • 根据我的经验,它被那些不知道自己在做什么的人使用,并试图通过在提交后使用对象来欺骗系统.*显然*在提交后,您无法保证该对象的状态不再有效. (4认同)