maruthi reddy
maruthi reddy

Reputation: 653

Parent instance is not bound to a Session; lazy load operation of attribute ’account’ cannot proceed

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

Answers (6)

dstromberg
dstromberg

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

Timo
Timo

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

Devy
Devy

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

zzzeek
zzzeek

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

Farshid Ashouri
Farshid Ashouri

Reputation: 17719

I had the same problem with Celery. Adding lazy='subquery' to relationship solved my problem.

Upvotes: 15

Related Questions