Reputation: 5107
For performance reasons, our application loads certain SQLAlchemy model instances into memory at startup time. These instances are not expected to change through the life of the application, so this is a reasonable solution.
For the most part, this has been fine, but I have observed isolated incidences where a DetachedInstanceError: Instance <ZZZ at 0x3a23510> is not bound to a Session; attribute refresh operation cannot proceed
will appear, causing ongoing problems. This is the same error I would (expectedly) receive when attempting to access a lazy-loaded relationship on a similarly cached object.
The error appears to be caused by access to the .id attribute, which I would expect not to require any kind of DB refresh to access. What really bothers me is that I can not reproduce this exception consistently.
My question is what might cause this exception to occur and what techniques has anybody used for storing SQLAlchemy instances beyond the transaction that brought them to be?
Upvotes: 1
Views: 716
Reputation: 75317
.id
would be missing if the object were expired before it were placed into the cache. After a Session commits or rolls back, by default it expires all attributes, which refresh when next accessed.
It's not a given that .id
is what it is, as the object may have been deleted from the database or its primary key modified (both conditions would emit an ObjectDeletedError).
Solution is to cache your object before it gets expired, expunge() it from the session before the session expires everything, or disable expire_on_commit.
Upvotes: 2