Pydantic如何定义Request类使payload支持EcrPayload或S3Payload类型
Pydantic多类型载荷字段实现方案
- 首先修复现有代码的Union类型声明问题:你当前定义的
Union[EcrPayload]仅包含单个类型,需要把S3Payload也加入联合类型声明,再根据你使用的Pydantic版本做对应适配即可。
Pydantic V2 实现代码
V2原生支持联合类型的智能字段匹配,直接补全类型即可:
from pydantic import CamelModel from typing import Union class EcrPayload(CamelModel): repository_name: str version: str class S3Payload(CamelModel): bucket_name: str object_key_name: str class Request(CamelModel): # 写法1:兼容所有Python 3版本 payload: Union[EcrPayload, S3Payload] # 写法2:Python 3.10+ 可使用更简洁的管道语法 # payload: EcrPayload | S3Payload
如果需要更高的解析准确率,也可以给两种Payload添加相同的类型区分字段,配合discriminator参数使用,避免字段重叠导致的解析错误。
Pydantic V1 实现代码
V1默认会优先匹配联合类型中第一个符合结构的类型,容易出现解析偏差,需要额外开启smart_union配置,同时给Payload类添加extra = "forbid"配置避免多余字段被忽略:
from pydantic import BaseModel from typing import Union # 此处假设你使用的CamelModel是自定义的、继承自BaseModel的驼峰命名转换模型 class EcrPayload(CamelModel): repository_name: str version: str class Config: extra = "forbid" class S3Payload(CamelModel): bucket_name: str object_key_name: str class Config: extra = "forbid" class Request(CamelModel): payload: Union[EcrPayload, S3Payload] class Config: smart_union = True
- 效果验证代码示例:
# 验证EcrPayload解析 req1 = Request(**{"payload": {"repositoryName": "demo-repo", "version": "v1.2.3"}}) print(type(req1.payload)) # 输出 <class '__main__.EcrPayload'> # 验证S3Payload解析 req2 = Request(**{"payload": {"bucketName": "demo-bucket", "objectKeyName": "app.tar.gz"}}) print(type(req2.payload)) # 输出 <class '__main__.S3Payload'>
内容的提问来源于stack exchange,提问作者edmamerto
相关产品推荐
相关产品推荐

