I want to use AsyncAttrs of SQLAlchemy with Pydantic .from_obj method
I have a simple SQLAlchemy Model, with inherited AsyncAttrs as said in sqlalchemy doc: AsyncAttrs doc
class ModelBase(AsyncAttrs, DeclarativeBase):
...
class A(ModelBase):
__tablename__ = "a"
bs = relationship()
and pydantic schemas:
class BsRelationSchema(BaseModel):
id: int
name: str
class Config:
orm_mode = True
class ASchema(BaseModel):
bs: BsRelationSchema
class Config:
orm_mode = True
I can create instance of schema in this way:
a = (await session.scalars(select(A))).one()
a_schema = ASchema(bs=await a.awaitable_attrs.bs)
But how can i do this?
a = (await session.scalars(select(A))).one()
a_schema = ASchema.from_obj(a1)
I've been doing something similar lately, and there are two methods that I've used so far. It touches upon some of the things mentioned by DurandA, but a little less complex. The methods described below are taken from SQLAlchemy documentation
(Please also note I'll be using the new model_validate instead of from_orm, as described in Pydantic migration guide, but it works the same with from_orm
, just trying to avoid the deprecated method.)
Anyway, method 1: after you get each object, you do an await on their awaitable_attrs before creating the schema. Yes, I am aware that is what you posted, I just wanted to write it here for completeness.
a = (await session.scalars(select(A))).one()
await a.awaitable_attrs.bs
a_schema = ASchema.model_validate(a)
Method 2: using the selectinload eager loader. You can modify your query to:
a = (await session.scalars(select(A).options(selectinload(A.bs)))).one()
a_schema = ASchema.model_validate(a)
Hope this helps!
Update: please be aware that this is just one way of relationship loading styles and they correspond to different SQL queries. Please have a look at Relationship Loading Techniques to learn more.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With