如何让Pydantic模型字段校验枚举名称而非枚举值?
实现Pydantic模型通过枚举名称校验字段
问题场景
我定义了如下枚举类:
class DataType(Enum): TIMESTAMP = MyClass("ts") DATETIME = MyClass("dt") DATE = MyClass("date")
同时定义了包含该枚举类型字段的Pydantic模型:
class Aggregation(BaseModel): field_data_type: DataType
希望Pydantic校验字段时匹配枚举的名称而非值,支持通过以下方式实例化模型:
agg = Aggregation(field_data_type="TIMESTAMP")
解决方案
方法1:自定义字段验证器(兼容Pydantic v1/v2)
给模型字段添加前置验证器,将输入的字符串映射到对应的枚举成员:
from pydantic import BaseModel, field_validator from enum import Enum class MyClass: def __init__(self, value): self.value = value class DataType(Enum): TIMESTAMP = MyClass("ts") DATETIME = MyClass("dt") DATE = MyClass("date") class Aggregation(BaseModel): field_data_type: DataType @field_validator('field_data_type', mode='before') def parse_enum_name(cls, v): if isinstance(v, str): try: return DataType[v] except KeyError: raise ValueError(f"无效的DataType名称: {v},可选值为{[e.name for e in DataType]}") return v
输入字符串时,验证器会先将其转换为对应的枚举成员,再完成后续校验。
方法2:封装通用枚举字段类型
如果多个模型需要相同逻辑,可以封装成自定义字段,避免重复代码:
from pydantic import GetCoreSchemaHandler from pydantic_core import core_schema from enum import Enum class EnumByNameField: @classmethod def __get_pydantic_core_schema__(cls, source_type, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: return core_schema.no_info_after_validator_function( lambda v: source_type[v] if isinstance(v, str) else v, handler(source_type), ) # 在模型中使用自定义字段 class Aggregation(BaseModel): field_data_type: DataType = EnumByNameField()
方法3:使用Pydantic v2的SmartEnum(推荐)
若使用Pydantic v2,可直接借助SmartEnum实现原生支持,它能自动识别枚举名称或值进行解析:
from pydantic import BaseModel from pydantic.types import SmartEnum class MyClass: def __init__(self, value): self.value = value class DataType(SmartEnum): TIMESTAMP = MyClass("ts") DATETIME = MyClass("dt") DATE = MyClass("date") class Aggregation(BaseModel): field_data_type: DataType
此时直接用Aggregation(field_data_type="TIMESTAMP")即可正常实例化模型。
内容的提问来源于stack exchange,提问作者Onca
相关产品推荐
相关产品推荐

