在Pydantic中如何动态创建嵌套模型解析AWS GuardDuty JSON数据?
问题原因
你当前的写法生成的是空模型,自然无法解析嵌套字段:调用create_model("ServiceModel")时没有传入任何字段定义,生成的ServiceModel默认没有任何字段,且默认会忽略未定义的额外字段,因此解析后嵌套内容全部丢失。
解决方法
根据你的使用场景可以选择以下两种方案:
场景1:无需提前定义嵌套字段,保留所有传入的嵌套内容
这是处理AWS GuardDuty这类结构不固定的嵌套数据最简便的方案,只需要给动态生成的模型配置允许接收额外字段即可:
Pydantic V2 写法
from pydantic import BaseModel, create_model data = { "test": "test", "dynamic_json":{ "dyn1": "dyn1_v", "dyn2": "dyn2_v", "dyn3": "dyn3_v" }, "test2":"test2" } class TestModel(BaseModel): test: str # 给动态模型配置允许额外字段 dynamic_json: create_model("DynamicJsonModel", model_config={"extra": "allow"}) test2: str m = TestModel.parse_obj(data) print(m.dynamic_json.dyn1) # 输出 dyn1_v print(m.model_dump()) # 可看到完整的嵌套字段
Pydantic V1 写法
from pydantic import BaseModel, create_model class TestModel(BaseModel): test: str dynamic_json: create_model("DynamicJsonModel", __config__=type('Config', (), {'extra': 'allow'})) test2: str
场景2:需要根据样例数据生成固定字段的动态模型
如果你需要基于已有样例数据的结构生成严格的模型(仅接收样例中存在的字段,自动做类型校验),可以先从样例数据提取字段定义再生成模型:
from pydantic import BaseModel, create_model data = { "test": "test", "dynamic_json":{ "dyn1": "dyn1_v", "dyn2": "dyn2_v", "dyn3": "dyn3_v" }, "test2":"test2" } # 从样例数据提取动态字段的类型定义 dynamic_fields = { key: (type(value), ...) for key, value in data["dynamic_json"].items() } # 生成带固定字段的动态模型 DynamicJsonModel = create_model("DynamicJsonModel", **dynamic_fields) class TestModel(BaseModel): test: str dynamic_json: DynamicJsonModel test2: str m = TestModel.parse_obj(data) print(m) # 输出:test='test' dynamic_json=DynamicJsonModel(dyn1='dyn1_v', dyn2='dyn2_v', dyn3='dyn3_v') test2='test2'
替代方案:直接用字典类型接收
如果不需要嵌套内容为BaseModel实例,仅需要保留数据,直接将字段类型声明为dict即可,不需要用create_model:
from pydantic import BaseModel from typing import Dict, Any class TestModel(BaseModel): test: str dynamic_json: Dict[str, Any] test2: str
内容的提问来源于stack exchange,提问作者SnowBoundShip53
相关产品推荐
相关产品推荐

