我在自己的
similar question上工作时遇到了关于属性到期的问题.实例分离.
univerio给了我一个很好的答案,从我学到的东西,我或许可以对你的问题有所了解.
在我的情况下,我正在创建,提交或回滚,然后在一个带有… as …子句的单个范围内关闭一个Session,然后尝试立即访问我保存的实例(示例中的obj)之后但超出了该条款的范围.在我尝试引用已保存的对象之前,会话已关闭.默认情况下,在SQLAlchemy中,如果没有活动的Session,则无法访问持久化的属性/对象,除非明确告知允许它.这是为了通过强制应用程序首先查询/检索更新的数据来意外地或不知不觉地使用过时/不正确的数据来“保护”代码,这需要关联的会话.因此,在我的情况下,在提交后保持会话打开意味着对象可以使用该会话来查询数据库,以防记录自首次编写以来已被修改.
在你的情况下,用于通过objs = SomeModel.query.all()获取对象的Session在查询之后但在调用obj.backref之前被关闭或断开(虽然我不确定如何;我不是知道SomeModel是什么,确切地说,我假设是Flask的一个构造,它在后台包含了一个Session.因此obj不再具有与数据库的连接,因此是“分离的”.通过将其添加到db_session,您允许obj重新建立与其源数据库的连接,通过它可以查询以检查更新的属性,因此它不再分离.
最后,值得一提的是,通过指定与obj关联的原始会话不会自动使属性过期,可以避免DetachedInstanceError.如果没有使obj过期,则不会抛出错误,但obj仍然会被分离,这意味着当您调用obj.backref时,返回的值可能不正确/过时.您询问了在问题中的分离,但过期是一个相关但不完全相同的概念.
除此之外 – 如何设置obj不会过期:在Session初始化时
my_session = sessionmaker(expire_on_commit=False
sessionmaker的初始化
my_sessionmaker = sqlalchemy.orm.sessionmaker(expire_on_commit=False)
甚至在会话已经实例化之后
my_session.expire_on_commit = False