首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >读取分离的sqlalchemy对象的属性会引发DetachedInstanceError。

读取分离的sqlalchemy对象的属性会引发DetachedInstanceError。
EN

Stack Overflow用户
提问于 2019-10-23 21:44:34
回答 1查看 1.1K关注 0票数 2

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

代码语言:javascript
复制
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)
代码语言:javascript
复制
# 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属性
  • 从会话中删除对象并保持会话打开。仍然是分离状态,但我可以访问属性。

我应该能够读取独立对象的属性吗?是否有一种方法可以使对象安全地超过临时会话?我在输出中阅读了建议的链接,但它主要讨论的是父/子关系。

我在sqlalchemy上创建了一个问题,因为我起初以为这是个bug,但现在我不太确定了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-23 22:53:23

深入研究这一点,发现我在会话中被expire_on_commit为true的默认值咬了一口。在打开时,commit调用将过期对象,这迫使sqlalchemy在下次读取属性时重新加载它。如果延迟到会话关闭后,则无法获取属性。

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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58531384

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档