如何用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
相关产品推荐
相关产品推荐

