Lỗi xuất hiện khi code chạm vào một thuộc tính cần IO ngầm ở nơi không await được: SQLAlchemy nạp relationship theo cơ chế đồng bộ, còn với AsyncSession mọi IO phải đi qua lớp greenlet — truy cập order.items ngoài ngữ cảnh đó là lỗi.
Hai nguồn gốc phổ biến:
1. Lazy load relationship. Mặc định relationship là lazy; lần đầu đọc sẽ phát query.
python
# fix 1: nap san khi truy van
stmt = select(Order).options(selectinload(Order.items))
order = (await db.scalars(stmt)).first()
order.items # already loaded
# fix 2: mixin AsyncAttrs, await tuong minh
order = await db.get(Order, order_id)
items = await order.awaitable_attrs.items- **2.
- Thuộc tính bị expire sau
commit().** Mặc địnhexpire_on_commit=Truelàm mọi thuộc tính hết hiệu lực; lần đọc kế tiếp cần một query refresh mà async không tự chạy được. - Vì vậy session factory async nên đặt
expire_on_commit=False:
python
SessionLocal = async_sessionmaker(engine, expire_on_commit=False)Trong FastAPI, lỗi này hay lộ ra ở bước serialize response_model: handler commit xong rồi trả object, Pydantic đọc field và nổ.
Nguyên tắc là nạp đủ dữ liệu trước khi rời session, và ưu tiên selectinload cho quan hệ một-nhiều để tránh cả MissingGreenlet lẫn N+1.