Reputation: 653
While trying to do the following operation:
for line in blines:
line.account = get_customer(line.AccountCode)
I am getting an error while trying to assign a value to line.account
:
DetachedInstanceError: Parent instance <SunLedgerA at 0x16eda4d0> is not bound to a Session; lazy load operation of attribute 'account' cannot proceed
Am I doing something wrong??
Upvotes: 42
Views: 64907
Reputation: 7187
I just saw this myself, and thought I'd share what fixed it for me.
I wanted to iterate over a dict and change it at the same time, so I copy.deepcopy
'd dict_.items()
to avoid the common problem that comes from iterating and mutating a dict at the same time.
But I had copy.deepcopy
'd a list containing some SQLAlchemy ORM objects, which separated the copies from their session, even though they seemed to be suitable objects in other ways.
Fix: Don't copy.deepcopy
them. I just did list(dict_.items())
instead of copy.deepcopy(dict_.items())
. The list()
makes it eager.
Upvotes: 0
Reputation: 21
To access the attribute connected to other table, you should call it within session.
@contextmanager
def get_db_session(engine):
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
db = SessionLocal()
try:
yield db
except Exception:
db.rollback()
raise
finally:
db.close()
with get_db_session(engine) as sess:
data = sess.query(Groups).all()
# `group_users` is connected to other table
print([x.group_users for x in data]) # sucess
print([x.group_users for x in data]) # fail
Upvotes: 2
Reputation: 61
I had the same problem when unittesting.
The solution was to call everything within the "with" context:
with self.app.test_client() as c:
res = c.post('my_url/test', data=XYZ, content_type='application/json')
Then it worked.
Adding the lazy attribute didn't work for me.
Upvotes: 4
Reputation: 10199
I encountered this type of DetachedInstanceError
when I prematurely close the query session (that is, having code to deal with those SQLAlchemy model objects AFTER the session is closed). So that's one clue to double check no session closure until you absolutely don't need interact with model objects, I.E. some Lazy Loaded model attributes etc.
Upvotes: 4
Reputation: 75307
"detached" means you're dealing with an ORM object that is not associated with a Session
. The Session
is the gateway to the relational database, so anytime you refer to attributes on the mapped object, the ORM will sometimes need to go back to the database to get the current value of that attribute. In general, you should only work with "attached" objects - "detached" is a temporary state used for caching and for moving objects between sessions.
See Quickie Intro to Object States, then probably read the rest of that document too ;).
Upvotes: 36
Reputation: 17719
I had the same problem with Celery. Adding lazy='subquery'
to relationship solved my problem.
Upvotes: 15