我想从我的会话中分离一个类的实例,但它仍然可以读取(不会发出查询)。我现在已经扫描了几天的文档,但我尝试的每一种方法都会导致消息
DetachedInstanceError: Instance <MyModel at 0x36bb190> is not bound to a Session;
attribute refresh operation cannot proceed
我正在使用Pyramid中的zope.sqlalchemy
交易管理器。我希望我的对象在提交事务后可用。我只需要它来读取“缓存”值,即提交事务之前的值。
我能弄明白的唯一方法是包装类(或属性本身),然后手动跟踪更改(我可以这样做,但它真的很难看,而且根本不是pythonic)。
那么有什么办法可以阻止SQLAlchemy尝试刷新这些值吗?
作为一个后备,我甚至愿意只返回None
,只要在事务提交后没有抛出上述错误
答案 0 :(得分:10)
http://docs.sqlalchemy.org/en/latest/orm/session_api.html
我认为你正在寻找expire_on_commit = False
我相信这允许你分离对象并继续使用它。然而,尝试修改它并提交将导致DetachedInstanceError
。
答案 1 :(得分:6)
您可以通过执行以下操作(例如缓存):
session.expunge(obj)
根据sqlalchemy文档:
这将为您提供可以安全使用的处于分离状态的对象 - 您需要记住,您将无法读取会发出另一个查询的属性,从而与会话相关联,这将最终导致DetachedInstanceError
。
默认情况下,提交将发出expire_all(),这意味着所有对象将在读取时刷新其状态,方法是将它们与会话分离,以便在提交事务后不再有后续查询。
我建议不要在全球范围内禁用此功能,因为其他评论建议Mike Bayer一般认为这对大多数人来说是一个好主意和理智的默认设置,可以帮助您长期避免头痛。
当你需要时,明确地解决问题。
答案 2 :(得分:3)
试试这个:
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension(), expire_on_commit=False))
我也遇到了这个问题,使用expire_on_commit=False
解决了我的问题。
答案 3 :(得分:2)
<asp:DataList ID="ddlpro" runat="server" onItemBound="dllpro">//parent ds
<ItemTemplate>
<asp:Label ID="ImgName" runat="server" Text='<%#Eval("a1") %>' ></asp:Label>
<asp:DataList ID="ddlchild" runat="server" onItemBound="dllchild">//child ds
<a href='<%#Eval("a1") %>' ID=Btn><asp:Label>'<%#Eval("Idname") %>'</asp:Label>
.
.
All closing tags