我正在嘗試獲取一對多關系中匹配的行數。當我嘗試時,parent.children_count我得到:
sqlalchemy.exc.MissingGreenlet:尚未呼叫greenlet_spawn;不能在這里呼叫 await_only()。是否在意想不到的地方嘗試了 IO?(此錯誤的背景:https ://sqlalche.me/e/14/xd2s )
我添加expire_on_commit=False但仍然得到同樣的錯誤。我怎樣才能解決這個問題?
import asyncio
from uuid import UUID, uuid4
from sqlmodel import SQLModel, Relationship, Field
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
class Parent(SQLModel, table=True):
id: UUID = Field(default_factory=uuid4, primary_key=True)
children: list["Child"] = Relationship(back_populates="parent")
@property
def children_count(self):
return len(self.children)
class Child(SQLModel, table=True):
id: UUID = Field(default_factory=uuid4, primary_key=True)
parent_id: UUID = Field(default=None, foreign_key=Parent.id)
parent: "Parent" = Relationship(back_populates="children")
async def main():
engine = create_async_engine("sqlite aiosqlite://")
async with engine.begin() as conn:
await conn.run_sync(SQLModel.metadata.create_all)
async with AsyncSession(engine) as session:
parent = Parent()
session.add(parent)
await session.commit()
await session.refresh(parent)
print(parent.children_count) # I need 0 here, as of now this parent has no children
asyncio.run(main())
uj5u.com熱心網友回復:
我認為這里的問題是默認情況下 SQLAlchemy 延遲加載關系,因此parent.children_count隱式訪問會觸發導致報告錯誤的資料庫查詢。
解決此問題的一種方法是在關系定義中指定“惰性”以外的加載策略。使用 SQLModel,這看起來像:
children: list['Child'] = Relationship(
back_populates='parent', sa_relationship_kwargs={'lazy': 'selectin'}
)
這將導致 SQLAlchemy 在仍處于“異步模式”時發出額外的查詢以獲取關系。另一種選擇是 pass {'lazy': 'joined'},這將導致 SQLAlchemy 在單個JOIN查詢中獲取所有結果。
如果不希望配置關系,您可以發出指定選項的查詢:
from sqlalchemy.orm import selectinload
from sqlmodel import select
...
async with AsyncSession(engine) as session:
parent = Parent()
session.add(parent)
await session.commit()
result = await session.scalars(
select(Parent).options(selectinload(Parent.children))
)
parent = result.first()
print(
parent.children_count
) # I need 0 here, as of now this parent has no children
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/525574.html
