python 使用异步SQLAlchemy访问多对一相关对象[重复]

ikfrs5lh  于 2022-12-25  发布在  Python
关注(0)|答案(1)|浏览(171)
    • 此问题在此处已有答案**:

MissingGreenlet: greenlet_spawn has not been called(1个答案)
20小时前关门了。
我有两个模型:

class A(Base):
  __tablename__ = 'a'

  id = sa.Column(sa.Integer(), primary_key=True)

class B(Base):
  __tablename__ = 'b'

  id = sa.Column(sa.Integer(), primary_key=True)
  a_id = sa.Column(sa.Integer(), sa.ForeignKey(A.id))
  a = relationship(A)

现在,如果我从B获取一个对象并用b.a查询其a属性,则会得到以下错误

sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/14/xd2s)

var = b.a放在async with session.begin():块中,或将其称为await b.a(事后看来这很愚蠢,但必须尝试所有方法)没有任何帮助。
我可以

b_a = (await db.scalars(sa.select(A).filter(A.id == b.a_id))).one()

但对我来说太冗长了(而且对于复杂的关系来说真的很混乱)。
我发现了很多相反的解决方案(一对多和多对多),但没有一个适合这个用例。
更新以回答评论中的问题:
我像这样创建引擎和会话生成器:

db_engine = create_async_engine(DB_URI, pool_recycle=3600, pool_pre_ping=True, echo_pool=True)
session_maker = sessionmaker(db_engine, AsyncSession, expire_on_commit=False, autocommit=False, autoflush=False)

我查询B对象的方式是:

query = sa.select(B).filter(B.id == requested_id)
result = (await db.execute(query)).one_or_none()  # type: ignore
b = result[0] if result else None
vlju58qv

vlju58qv1#

使用以下命令修改B类关系:
a =关系(A,惰性=“选择”)
这应该能正常工作

相关问题