gpt4 book ai didi

python - 读取分离的 sqlalchemy 对象的属性会引发 DetachedInstanceError

转载 作者:行者123 更新时间:2023-12-02 19:49:22 35 4
gpt4 key购买 nike

我正在使用短暂的 sqlalchemy session 将对象添加到 sqlite 数据库。一些对象以只读、分离状态比 session 更有效。不幸的是,如果 session 已关闭,访问分离对象的属性会引发异常。这是一个简化的代码示例

from sqlalchemy import Column, String, Integer, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

Base = declarative_base()

class Foo(Base):
__tablename__ = 'foo'
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)

engine = create_engine('sqlite:///foo.db', echo=False)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

f = Foo(name='foo1')
print('state=transient : name=', f.name)
session.add(f)
print('state=pending : name=', f.name)
session.commit()
session.close()
print('state=detached : name=', f.name)
# output
state=transient : name= foo1
state=pending : name= foo1
Traceback (most recent call last):
File "scratch_46.py", line 23, in <module>
print('state=detached : name=', f.name)
File "lib/python3.7/site-packages/sqlalchemy/orm/attributes.py", line 282, in __get__
return self.impl.get(instance_state(instance), dict_)
File "lib/python3.7/site-packages/sqlalchemy/orm/attributes.py", line 705, in get
value = state._load_expired(state, passive)
File "lib/python3.7/site-packages/sqlalchemy/orm/state.py", line 660, in _load_expired
self.manager.deferred_scalar_loader(self, toload)
File "lib/python3.7/site-packages/sqlalchemy/orm/loading.py", line 913, in load_scalar_attributes
"attribute refresh operation cannot proceed" % (state_str(state))
sqlalchemy.orm.exc.DetachedInstanceError: Instance <Foo at 0x7f266c758ac8> is not bound to a Session; attribute refresh operation cannot proceed (Background on this error at: http://sqlalche.me/e/bhk3)

奇怪的是,如果我执行其中任何一个都不会抛出错误

  • 在对象处于持久状态时读取提交和关闭调用之间的name属性
  • 从 session 中删除对象并保持 session 打开。仍处于分离状态,但我可以访问该属性。

我应该能够读取分离对象的属性吗?有没有办法让对象安全地超过 transient session ?我阅读了输出中建议的链接,但它主要讨论父/子关系。

我创建了一个 an issue在 sqlalchemy 存储库上,因为起初我认为这是一个错误,但现在我不太确定。

最佳答案

进一步深入研究,发现 session 中 expire_on_commit 的默认值是 true,我有点不适应。当它打开时,commit 调用使对象过期,这迫使 sqlalchemy 在下次有人读取属性时重新加载它。如果延迟到 session 关闭之后,则无法获取属性。

我真的不想要这种自动过期,因为我知道我的对象处于良好状态并且在保存后是只读的。在 session 生成器中将 expire_on_commit 设置为 false 可解决此问题。

关于python - 读取分离的 sqlalchemy 对象的属性会引发 DetachedInstanceError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58531384/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com