分离SQLAlchemy实例,以便不进行刷新

时间:2013-03-13 22:24:58

标签: python sqlalchemy pyramid

我想从我的会话中分离一个类的实例,但它仍然可以读取(不会发出查询)。我现在已经扫描了几天的文档,但我尝试的每一种方法都会导致消息

DetachedInstanceError: Instance <MyModel at 0x36bb190> is not bound to a Session;
attribute refresh operation cannot proceed

我正在使用Pyramid中的zope.sqlalchemy交易管理器。我希望我的对象在提交事务后可用。我只需要它来读取“缓存”值,即提交事务之前的值。

我能弄明白的唯一方法是包装类(或属性本身),然后手动跟踪更改(我可以这样做,但它真的很难看,而且根本不是pythonic)。

那么有什么办法可以阻止SQLAlchemy尝试刷新这些值吗?

作为一个后备,我甚至愿意只返回None,只要在事务提交后没有抛出上述错误

4 个答案:

答案 0 :(得分:10)

http://docs.sqlalchemy.org/en/latest/orm/session_api.html

我认为你正在寻找expire_on_commit = False

我相信这允许你分离对象并继续使用它。然而,尝试修改它并提交将导致DetachedInstanceError

答案 1 :(得分:6)

您可以通过执行以下操作(例如缓存):

session.expunge(obj)

根据sqlalchemy文档:

http://docs.sqlalchemy.org/en/rel_1_0/orm/session_api.html?highlight=expire#sqlalchemy.orm.session.Session.expunge

这将为您提供可以安全使用的处于分离状态的对象 - 您需要记住,您将无法读取会发出另一个查询的属性,从而与会话相关联,这将最终导致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