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

如何用BaseModel方法将扁平数据解析为嵌套Pydantic模型?

Pydantic解析数据库JOIN扁平数据到嵌套模型

问题描述

我定义了两个Pydantic模型:

from pydantic import BaseModel


class Nested(BaseModel):
    id: int
    title: str


class Model(BaseModel):
    id: int
    nested_id: int
    nested: Nested

其中Model关联了Nested模型。我通过JOIN查询数据库得到扁平数据:data = {'id': 5, 'nested_id': 1, 'id_1': 1, 'title': 'хлеб'},希望将该数据解析并为Nested模型分配对应字段。请问BaseModel是否有内置方法可完成此解析?我不想手动处理字典,希望通过BaseModel的方法实现,目前使用parse_as_obj(List[Model], data)。

解决方案

Pydantic没有直接适配这种场景的内置方法,但可以通过以下几种方式实现自动映射,无需手动修改原始字典:

1. 字段别名映射

给Nested模型的字段指定对应扁平数据中的键名,解析时启用别名匹配:

from pydantic import BaseModel, Field

class Nested(BaseModel):
    id: int = Field(alias='id_1')
    title: str

class Model(BaseModel):
    id: int
    nested_id: int
    nested: Nested

# 解析时传入by_alias=True,让Pydantic识别别名
data = {'id': 5, 'nested_id': 1, 'id_1': 1, 'title': 'хлеб'}
model = Model.model_validate(data, by_alias=True)
print(model.nested.id)  # 输出 1
print(model.nested.title)  # 输出 хлеб

2. 开启populate_by_name配置

如果希望同时支持字段原名和别名解析,可以在模型配置中开启populate_by_name:

from pydantic import BaseModel, Field
from pydantic.config import ConfigDict

class Nested(BaseModel):
    model_config = ConfigDict(populate_by_name=True)
    id: int = Field(alias='id_1')
    title: str

class Model(BaseModel):
    model_config = ConfigDict(populate_by_name=True)
    id: int
    nested_id: int
    nested: Nested

data = {'id': 5, 'nested_id': 1, 'id_1': 1, 'title': 'хлеб'}
model = Model.model_validate(data)
print(model.nested)  # 输出 Nested(id=1, title='хлеб')

3. 自定义根验证器提取嵌套数据

如果数据库返回的字段命名有固定规律(比如嵌套字段加后缀_1),可以用根验证器自动提取并组装嵌套数据:

from pydantic import BaseModel, root_validator

class Nested(BaseModel):
    id: int
    title: str

class Model(BaseModel):
    id: int
    nested_id: int
    nested: Nested

    @root_validator(pre=True)
    def extract_nested(cls, values):
        # 从扁平数据中提取Nested所需字段并组装
        values['nested'] = {
            'id': values.pop('id_1'),
            'title': values.pop('title')
        }
        return values

data = {'id': 5, 'nested_id': 1, 'id_1': 1, 'title': 'хлеб'}
model = Model.model_validate(data)
print(model.nested)  # 输出 Nested(id=1, title='хлеб')

注意:你提到的parse_as_obj是Pydantic v1的API,v2版本已统一使用model_validate(解析字典)或model_validate_json(解析JSON字符串),建议升级到v2以获得更稳定的功能支持。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 06:40:26