Async SQLAlchemy中selectin预加载空关系访问触发懒加载报错如何解决
问题原因
- 你在relationship中指定的
lazy='selectin'仅定义懒加载触发时采用的查询策略,不会让SQLAlchemy在查询主实体时自动预加载关联数据。session.get()默认仅查询主表字段,返回的实例中friends属性仍处于未加载状态,首次访问会自动触发懒加载逻辑。 - SQLAlchemy异步场景下不支持同步隐式触发懒加载:懒加载需要执行数据库IO,异步IO必须在可等待的上下文内执行,你直接同步访问
created_person.friends没有对应的异步调度上下文,因此触发MissingGreenlet报错。
规避方案
方案1:查询时主动预加载关联属性
调用session.get()时通过options指定selectinload主动加载friends关联,查询阶段就把关联数据拉取到内存,后续访问不会触发懒加载:
from sqlalchemy.orm import selectinload # 修改查询语句,注意session.get第一个参数应为实体类而非实例 created_person = await session.get(Person, person_id, options=[selectinload(Person.friends)]) print(created_person.friends) # 正常返回空列表
方案2:用异步方式加载关联属性
如果不需要预加载,可以通过awaitable_attrs异步触发懒加载,适配异步上下文:
created_person = await session.get(Person, person_id) # 异步加载关联属性 friends = await created_person.awaitable_attrs.friends print(friends)
方案3:初始化时主动赋值空关联
如果确定插入的实例无关联数据,可以在创建实例时直接给关联属性赋值空集合,标记属性为已加载状态,后续访问不会触发查询:
person = Person(id_=person_id, name='Alice', friends=[])
内容的提问来源于stack exchange,提问作者theo-brown
相关产品推荐
相关产品推荐

