Session SQLAlchemy课程:如何让它保持活力?

Session SQLAlchemy课程:如何让它保持活力?,session,transactions,sqlalchemy,python-3.2,Session,Transactions,Sqlalchemy,Python 3.2,我有一个session对象,它被传递了很多次,在某个时候调用了以下代码行(这是不可避免的): 这会导致会话无法使用(我认为是关闭它) 我的问题分为两部分: 如何检查会话是否仍然有效 有没有一个快速的方法来恢复一个死会话 对于2:我目前知道的唯一方法是使用sqlalchemy.orm.scoped_会话,然后多次调用query(…)get(id)来重新创建必要的模型实例,但这似乎非常低效 编辑 以下是导致错误的事件序列示例: modelInstance = DBSession.query(Mode

我有一个session对象,它被传递了很多次,在某个时候调用了以下代码行(这是不可避免的):

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

我的问题分为两部分:

  • 如何检查会话是否仍然有效
  • 有没有一个快速的方法来恢复一个死会话
  • 对于2:我目前知道的唯一方法是使用sqlalchemy.orm.scoped_会话,然后多次调用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
    
    下面是错误:

    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
    
    这是真的

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

    齐泽克说, “一旦您访问过期对象上的任何内容,它将通过会话自动从数据库加载新状态,因此无需通知会话在此处执行任何操作。”


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

    因此这里首先要注意的是“导入事务”是一个名为。这是一个通用事务,通过zope.SQLAlchemy扩展控制任意数量的子任务,其中SQLAlchemy会话就是其中之一

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

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

    会话无法继续的一次是刷新失败,并且没有调用rollback()方法,当处于autocommit=False模式时,会话希望您在flush()失败时显式执行该操作。要查看会话是否处于此特定状态,在这种情况下,Session.is_active属性将返回False

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

    这就引出了很多问题,这就是你真正想做的。例如,“重新创建必要的模型实例”不是会话所做的事情,除非您引用的是已经过期的现有实例(它们的内脏已经清空)。一旦您访问过期对象上的任何内容,它将通过会话自动从数据库加载新状态,因此无需告诉会话在此处执行任何操作


    当然,它甚至可以完全关闭自动过期功能,但如果您在这里遇到问题,则意味着某些功能无法正常工作。好像你收到了一些错误信息。需要更详细的信息才能确切地了解您遇到的问题。

    我在提交事务时遇到问题,由于某种原因,在调用flush()时不会提交任何内容,并且提交()出现错误(用于我的sqlalchemy会话)。这就是我使用transaction.commit()的原因(请参阅)。我在某个地方读到这样做会导致sqlalchemy会话无法使用,似乎就是这样。附言:我喜欢你的工作:)