SQLAlchemy,将对象绑定到Session

Sar*_*ica 55 python sqlalchemy

出于各种原因,我试图从数据库中获取对象集合,并将其传递给另一个未连接到数据库的进程.我的代码看起来像下面的那个,但我一直在

sqlalchemy.exc.UnboundExecutionError: Instance <MyClass at 0x8db7fec> is not bound to a Session; attribute refresh operation cannot proceed
Run Code Online (Sandbox Code Playgroud)

当我尝试在get_list()方法之外查看列表中的元素时.

def get_list (obj):
    sesson = Session()
    lst = session.query(MyClass).all()
    session.close()
    return lst
Run Code Online (Sandbox Code Playgroud)

但是,如果我使用它

def get_list_bis (obj)
    session = Session()
    return session.query(MyClass).all()
Run Code Online (Sandbox Code Playgroud)

我能够使用元素,但担心会话的状态,因为它没有关闭.

我在这里错过了什么?

Pav*_*pin 60

如果您希望通过查询会话生成的一堆对象在会话范围之外可用,则需要为会话清除它们.

在第一个函数示例中,您需要添加一行:

session.expunge_all()
Run Code Online (Sandbox Code Playgroud)

之前

session.close()
Run Code Online (Sandbox Code Playgroud)

更一般地说,假设会话没有立即关闭,就像在第一个例子中一样.也许这是一个在Web请求的整个持续时间内保持活动的会话或类似的东西.在这种情况下,你不想这样做expunge_all.你会想要更多手术:

for item in lst:
    session.expunge(item)
Run Code Online (Sandbox Code Playgroud)

  • 但是......但是......"close()方法发出了一个expunge_all(),并释放了所有的事务/连接资源." 此语句位于您引用的页面上,至少返回0.6版本. (21认同)
  • 我还发现这没有帮助。我删除和/或关闭并没有帮助。我知道它已经过时并且未连接到数据库,那又怎样!我想查找,然后关闭。db 会话尽快将连接返回给池并继续使用“陈旧”对象,只是为了以 json 形式返回 api 响应,非常奇怪,这必须抛出异常。 (7认同)
  • 正如以上评论所指出的,此答案并不完全正确。简单地关闭一个会话应该会使该属性陈旧,但是可以使用。Session.commit()和Session.rollback()在给定默认配置的情况下会过期ORM加载状态,并在提交阻止过期之前清除,从而使属性保持陈旧状态。 (5认同)

Ant*_*ash 12

这通常是由于对象处于expired状态,对象在提交后过期,然后当这些过期的对象即将被使用时ORM尝试refresh它们,但是当对象从会话中分离时(由于该会话是例如关闭).可以通过使用expire_on_commit=Falseparam 创建会话来管理此行为.

>>> from sqlalchemy import inspect
>>> insp = inspect(my_object)
>>> insp.expired
True  # then it will be refreshed...
Run Code Online (Sandbox Code Playgroud)