Menu

SQLAlchemy MissingGreenlet in Async Code: Fix Lazy Loading With selectinload, awaitable_attrs, or lazy="raise"
📰

SQLAlchemy MissingGreenlet in Async Code: Fix Lazy Loading With selectinload, awaitable_attrs, or lazy="raise"

DEV Community: backend·Libme·about 16 hours ago
#7gb6m6w1
#devtobackend#devto#dev#author#session
Reading 0:00
15s threshold

sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here means you touched a relationship or expired column that wasn't loaded, and SQLAlchemy tried to run a lazy-load query from synchronous attribute access inside an async session. The durable fix is to decide at query time which relationships you need ( selectinload or joinedload ) instead of letting attribute access trigger I/O. Use awaitable_attrs for the occasional one-off, and lazy="raise" to turn the bug into a loud, early failure. (Written against SQLAlchemy 2.0.x as of late 2026.)

Why does MissingGreenlet happen?

In a sync session, author.books on an unloaded relationship quietly emits a SELECT and returns the list. That works because attribute access is a plain Python call and the driver call blocks.

In an async session, the driver call must be awaited, but author.books is not awaitable. SQLAlchemy's async layer runs sync-style ORM code inside a greenlet so that it can bridge to await .…

Continue reading — create a free account

Join HashtagPLUS to read full articles, follow hashtags, vote, and join the conversation.