将嵌套 SQAlchemy 对象转换为 Pydatinc

问题描述 投票:0回答:1

假设我有下面的 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

执行此映射的优雅方法是什么?

sqlalchemy pydantic pydantic-v2
1个回答
0
投票
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",
        }
© www.soinside.com 2019 - 2024. All rights reserved.