Skip to content
Latchkey

SQLAlchemy "DetachedInstanceError" lazy-load after commit in CI

SQLAlchemy raises DetachedInstanceError when you access an attribute that needs a database round trip on an object whose session has been closed or whose state was expired (the default after commit). Tests that read relationships after the session ends hit this.

What this error means

A test fails with "sqlalchemy.orm.exc.DetachedInstanceError: Instance <Order at 0x...> is not bound to a Session; attribute refresh operation cannot proceed" when reading a relationship or expired column.

python
sqlalchemy.orm.exc.DetachedInstanceError: Instance <Order at 0x7f...> is not bound
to a Session; attribute refresh operation cannot proceed (Background on this error at:
https://sqlalche.me/e/20/bhk3)

Common causes

Accessing a lazy attribute after the session closed

The object was loaded in a with Session() block; reading a relationship outside that block needs a query, but the session is gone.

Default expire_on_commit refreshes attributes

After commit(), attributes are expired and reloaded lazily on next access; if the session is closed by then, the refresh fails.

How to fix it

Keep the session open or eager-load

  1. Read needed attributes while the session is still open.
  2. Eager-load relationships with selectinload/joinedload so no later query is needed.
  3. Or set expire_on_commit=False so committed objects stay usable.
python
from sqlalchemy.orm import selectinload
stmt = select(Order).options(selectinload(Order.items))
orders = session.execute(stmt).scalars().all()  # items already loaded

Disable expire-on-commit for the test session

Keep attributes populated after commit so assertions outside the session still work.

python
Session = sessionmaker(engine, expire_on_commit=False)

How to prevent it

  • Eager-load relationships you will read after the session closes.
  • Read attributes inside the session scope in tests.
  • Set expire_on_commit=False when objects outlive their session.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →