假设我有下面的 SQLAlchemy 模型:
class PhoneNumber(BaseModel):
__tablename__ = "phone_numbers"
life_id = mapped_column(
UUID(as_uuid=True),
ForeignKey("lives.id", ondelete="CASCADE"),
nullable=False,
)
number = mapped_column(String, nullable=False)
external_id = mapped_column(String, nullable=False)
life = relationship("Life", back_populates="phone_numbers")
class Life(BaseModel):
__tablename__ = "lives"
registration_number = mapped_column(String(11))
first_name = mapped_column(String(255))
last_name = mapped_column(String(255))
preferred_name = mapped_column(String(255))
gender = mapped_column(Enum(Gender))
birth_date = mapped_column(Date)
gender_identity = mapped_column(Enum(GenderIdentity))
email = mapped_column(String(512))
phone_numbers = relationship("PhoneNumber", back_populates="life", lazy="selectin")
然后我有一个如下的 pydantic 模型:
class ORMBaseModel(BaseModel):
model_config = ConfigDict(from_attributes=True)
class RootLifeSchema(ORMBaseModel):
first_name: Optional[str] = None
last_name: Optional[str] = None
preferred_name: Optional[str] = None
registration_number: Optional[str] = Field(
default=None, min_length=11, max_length=11
)
birth_date: Optional[date] = None
email: Optional[str] = None
gender: Optional[Gender] = None
email: Optional[str] = None
preferred_name: Optional[str] = None
gender_identity: Optional[GenderIdentity] = None
class LifeSchema(RootLifeSchema):
phone_numbers: Optional[List[PhoneNumberResource]] = []
class PhoneNumberSchema(ORMBaseModel):
number: Optional[str] = None
class PhoneNumberResource(ORMBaseModel):
id: UUID
type: str = "phone_numbers"
attributes: PhoneNumberSchema
开
LifeSchema.model_validate(life)
它正在上升:
pydantic_core._pydantic_core.ValidationError:1 个验证错误 LifeSchema Phone_numbers.0.attributes
我知道 Pydantic 无法将
PhoneNumber
映射到 PhoneNumberResource
执行此映射的优雅方法是什么?
class PhoneNumberResource(ORMBaseModel):
id: UUID
type: str = "phone_numbers"
attributes: PhoneNumberSchema
@model_validator(mode="before")
def transform(cls, data: dict) -> dict:
return {
"attributes": PhoneNumberSchema.model_validate(data),
"id": data.id,
"type": "phone_numbers",
}