You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从单个SQLAlchemy对象生成Pydantic嵌套结构?

如何从SQLAlchemy对象生成Pydantic嵌套属性

问题背景

现有SQLAlchemy模型:

class FooORM(BaseORM):
    __tablename__ = 'foo'
    id = Column(Integer)
    cost_high = Column(Integer)
    cost_low = Column(Integer)

对应的初始Pydantic模型:

from pydantic import BaseModel, ConfigDict    
class FooModel(BaseModel):
    model_config = ConfigDict(from_attributes=True) 
    id: int
    cost_high: int
    cost_low: int

当前输出结构:

{"id": 1, "cost_high": 5, "cost_low": 0}

期望输出结构:

{"id": 1, "cost": {"high": 5, "low": 0}}

尝试定义嵌套Cost模型后,无法自动将cost_high映射到Cost.high,需要实现反向的属性嵌套转换。


解决方案

方法1:使用Pydantic v2+的computed_field(简单直观)

通过计算属性动态生成嵌套的cost字段,保留原ORM字段映射的同时生成期望的嵌套结构:

from pydantic import BaseModel, ConfigDict, computed_field

class Cost(BaseModel):
    high: int
    low: int

class FooModel(BaseModel):
    model_config = ConfigDict(from_attributes=True) 
    id: int
    cost_high: int
    cost_low: int

    @computed_field
    @property
    def cost(self) -> Cost:
        return Cost(high=self.cost_high, low=self.cost_low)

方法2:字段别名映射(隐藏原扁平字段)

如果不需要在FooModel中暴露cost_high和cost_low,可以通过Field的validation_alias直接完成映射:

from pydantic import BaseModel, ConfigDict, Field

class Cost(BaseModel):
    high: int = Field(validation_alias="cost_high")
    low: int = Field(validation_alias="cost_low")

class FooModel(BaseModel):
    model_config = ConfigDict(from_attributes=True) 
    id: int
    cost: Cost

方法3:自定义模型验证器(复杂场景适配)

针对多输入类型或复杂转换逻辑,使用model_validator手动处理属性映射:

from pydantic import BaseModel, ConfigDict, model_validator

class Cost(BaseModel):
    high: int
    low: int

class FooModel(BaseModel):
    model_config = ConfigDict(from_attributes=True) 
    id: int
    cost: Cost

    @model_validator(mode="before")
    def unpack_cost_fields(cls, values):
        # 适配ORM对象输入
        if isinstance(values, FooORM):
            return {
                "id": values.id,
                "cost": {"high": values.cost_high, "low": values.cost_low}
            }
        # 适配字典输入
        values["cost"] = {
            "high": values.pop("cost_high"),
            "low": values.pop("cost_low")
        }
        return values

内容的提问来源于stack exchange,提问作者PGHE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 09:33:32