如何为根键随type动态变化的结构创建Pydantic模型?
用Pydantic处理动态结构的JSON
针对你提到的两种随type字段变化的JSON结构,这里提供两种实用的Pydantic建模方案:
方案一:联合子类模型(兼容Pydantic v1/v2)
先分别为两种type定义专属模型,再通过Union组合成动态模型:
from pydantic import BaseModel, Field from typing import Union # 对应type="thirdparty"的模型 class ThirdParty(BaseModel): type: str = Field("thirdparty", const=True) # 固定type值,确保匹配 key: str host: str id: str # 对应type="weburl"的模型 class WebUrl(BaseModel): type: str = Field("weburl", const=True) url: str # 动态模型,自动根据type字段匹配对应子类 DynamicModel = Union[ThirdParty, WebUrl]
使用时,Pydantic会自动识别JSON里的type值,匹配对应的模型实例。
方案二:带鉴别器的联合模型(Pydantic v2+ 推荐)
如果用的是Pydantic v2及以上版本,用discriminator可以更精准地指定区分字段,避免潜在的匹配歧义:
from pydantic import BaseModel, Field, Discriminator from typing import Union class ThirdParty(BaseModel): type: str = "thirdparty" key: str host: str id: str class WebUrl(BaseModel): type: str = "weburl" url: str class DynamicModel(BaseModel): __root__: Union[ThirdParty, WebUrl] = Field(..., discriminator='type')
这里通过__root__包裹联合类型,并指定discriminator='type',Pydantic会严格依据type字段的值选择对应模型,解析效率和可读性都更好。
验证示例
可以用以下代码验证模型的有效性:
# 解析第三方服务类型JSON thirdparty_data = { "type": "thirdparty", "key": "postgres", "host": "test", "id": "88c8fo90" } obj1 = DynamicModel.model_validate(thirdparty_data) print(type(obj1)) # 方案一输出 <class '__main__.ThirdParty'> # 方案二需访问obj1.__root__,输出 <class '__main__.ThirdParty'> # 解析网页链接类型JSON weburl_data = { "type": "weburl", "url": "https://www.google.com" } obj2 = DynamicModel.model_validate(weburl_data) print(type(obj2)) # 方案一输出 <class '__main__.WebUrl'> # 方案二需访问obj2.__root__,输出 <class '__main__.WebUrl'>
内容的提问来源于stack exchange,提问作者Prajna
相关产品推荐
相关产品推荐

