【问题标题】:SQLAlchemy session: how to keep it alive?SQLAlchemy 会话:如何让它保持活力?
【发布时间】:2023-03-20 02:58:01
【问题描述】:

我有一个会话对象,它被大量传递,并且在某些时候调用了以下代码行(这是不可避免的):

import transaction
transaction.commit()

这会使会话无法使用(我认为是关闭它)。

我的问题分为两部分:

  1. 如何检查会话是否仍然有效?
  2. 有没有快速恢复死机会话的方法?

对于 2:我目前知道的唯一方法是使用 sqlalchemy.orm.scoped_session,然后多次调用 query(...)get(id) 来重新创建必要的模型实例,但这似乎非常低效。

编辑

以下是导致错误的事件序列示例:

modelInstance = DBSession.query(ModelClass).first()
import transaction
transaction.commit()
modelInstance.some_relationship

这是错误:

sqlalchemy.orm.exc.DetachedInstanceError: Parent instance <CategoryNode at 0x7fdc4c4b3110> is not bound to a Session; lazy load operation of attribute 'children' cannot proceed

我真的不想关闭延迟加载。

编辑

在这种情况下,DBSession.is_active 似乎没有表明会话实际上是否还活着并且很好:

transaction.commit()
print(DBSession.is_active)

这将打印 True...

编辑 这似乎太大了,无法发表评论,所以我把它放在这里。

zzzeek 说: “一个过期的对象会通过 Session 自动从数据库中加载新的状态,只要你访问它上面的任何东西,所以没有必要告诉 Session 在这里做任何事情。”

那么,我如何才能让事情发生这样的事情呢?调用transaction.commit是错误的,正确的方法是什么?

【问题讨论】:

    标签: session transactions sqlalchemy python-3.2


    【解决方案1】:

    所以这里首先要观察的是“导入事务”是一个名为zope.transaction 的包。这是一个通用事务,它通过 zope.sqlalchemy 扩展来处理任意数量的子任务,其中 SQLAlchemy 会话就是其中之一。

    这里的 zope.sqlalchemy 要做的是调用 Session 本身的 begin()/rollback()/commit() 方法,以响应它自己对“事务”的管理。

    会话本身的工作方式几乎总是可以使用,即使它的内部事务已经提交。发生这种情况时,下一次使用时的会话将继续进行,如果它处于 autocommit=False 则开始一个新事务,或者如果 autocommit=True 它继续以“自动提交”模式。基本上它是自动恢复活力的。

    Session 无法继续的一次是刷新失败,并且 rollback() 方法没有被调用,当处于 autocommit=False 模式时,Session 希望你明确地在什么时候做冲洗()失败。要查看 Session 是否处于此特定状态,在这种情况下 session.is_active 属性将返回 False。

    我不能 100% 确定在使用 zope.transaction 时继续使用 Session 的含义。我认为这取决于您如何在更大的方案中使用 zope.transaction。

    这将我们引导到许多这些问题的地方,这就是您真正想要做的事情。就像,“重新创建必要的模型实例”不是 Session 所做的事情,除非您指的是 existing 已过期的实例(它们的胆量被清空)。过期的对象会通过 Session 自动从数据库中加载新的状态,只要你访问它上面的任何东西,所以这里不需要告诉 Session 做任何事情。

    当然,您甚至可以选择完全关闭自动过期,但您甚至在这里遇到问题意味着某些事情无法正常工作。就像您收到一些错误消息一样。需要更多详细信息才能准确了解您遇到的问题。

    【讨论】:

    • 我在提交事务时遇到问题,由于某种原因,当我调用 flush() 并且 commit() 出现错误时(对于我的 sqlalchemy 会话),什么都不会提交。这就是我使用 transaction.commit() 的原因(参见 stackoverflow.com/questions/12446220/…)。我在某处读到,这样做会导致 sqlalchemy 会话无法使用,似乎就是这种情况。 PS:我喜欢你的工作:)
    猜你喜欢
    • 2023-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 1970-01-01
    • 2015-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多