2012-04-02 73 views
1

由於性能方面的原因,我們的應用程序在啓動時將某些SQLAlchemy模型實例加載到內存中。預計這些實例在應用程序的整個生命週期中不會改變,所以這是一個合理的解決方案。SQLAlchemy超越事務緩存對象

大多數情況下,這一直很好,但我已經觀察到孤立事件,其中DetachedInstanceError: Instance <ZZZ at 0x3a23510> is not bound to a Session; attribute refresh operation cannot proceed將出現,導致持續的問題。這是我嘗試訪問類似緩存對象上的延遲加載關係時(預期)會收到的相同錯誤。

該錯誤似乎是由訪問.id屬性引起的,我希望不需要任何類型的數據庫刷新即可訪問。真正困擾我的是,我無法一直重現這個異常。

我的問題是什麼可能會導致發生此異常,以及有人用什麼技術將SQLAlchemy實例存儲到使它們變爲事務的範圍之外?

+0

當你加載對象時,它將與會話相關聯,如果你可以檢查會話中的obj,那麼它會返回給你'真'。所以,當你嘗試訪問'.id'時,請檢查該對象是否存在於該會話中。 – Nilesh 2012-04-03 04:48:38

回答

2

.id如果對象在放入緩存之前已過期,它將會丟失。在會話提交或回滾之後,默認情況下會過期所有屬性,並在下次訪問時刷新。

.id是不是給定的,因爲該對象可能已從數據庫中刪除或其主鍵被修改(這兩個條件都會發出ObjectDeletedError)。

解決方案是在對象過期之前緩存對象,在會話過期之前將其從會話中清除(),或者禁用expire_on_commit。