You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pydantic 1.x中兼容驼峰/大驼峰格式数据验证(不可改基类)

如何在不修改Pydantic v1基类的前提下兼容camelCase与PascalCase格式数据验证

问题背景

现有待验证的数据对象:

{'d': {'results': [
    {'superHeroPublicId': '1', 'power': '100.00', 'infoText': 'irrelevant'},
    {'SuperHeroPublicId': '2', 'Power': '1541.60', 'InfoText': 'irrelevant'} 
]}}

以及无法修改的Pydantic v1基类:

class ApiPublicBaseModel(BaseModel):
    class Config:
        alias_generator = camelize
        allow_population_by_field_name = True
        extra = Extra.ignore
        json_encoders = {
            datetime: lambda value: value.isoformat(),
        }

需求:创建验证模型,同时兼容数据中的camelCase(小驼峰)和PascalCase(大驼峰)格式字段,避免验证失败。

解决方案

方法一:前置根验证器统一转换键名

在子类中添加前置根验证器,遍历输入数据的所有键,将PascalCase格式的键转换为camelCase,适配基类的别名规则。如果有嵌套结构,需要递归处理:

from pydantic import root_validator
from typing import Any, Dict
from pydantic.base import camelize

class SuperHero(ApiPublicBaseModel):
    super_hero_public_id: str
    power: str
    info_text: str

    @root_validator(pre=True)
    def normalize_case_keys(cls, values: Dict[str, Any]) -> Dict[str, Any]:
        def normalize_nested(d: Dict[str, Any]) -> Dict[str, Any]:
            normalized = {}
            for key, val in d.items():
                # 递归处理嵌套字典
                if isinstance(val, dict):
                    val = normalize_nested(val)
                # 大驼峰转小驼峰:首字母小写
                if key and key[0].isupper():
                    camel_key = key[0].lower() + key[1:]
                    normalized[camel_key] = val
                else:
                    normalized[key] = val
            return normalized
        return normalize_nested(values)

# 验证测试
data = {'d': {'results': [
    {'superHeroPublicId': '1', 'power': '100.00', 'infoText': 'irrelevant'},
    {'SuperHeroPublicId': '2', 'Power': '1541.60', 'InfoText': 'irrelevant'} 
]}}

for hero_item in data['d']['results']:
    hero = SuperHero(**hero_item)
    print(hero.dict(by_alias=True))  # 输出camelCase格式的结果

方法二:为字段手动映射多格式键

如果不想全局转换,可以为每个字段单独处理PascalCase的键,利用root_validator将大驼峰键的值赋值给对应字段:

class SuperHero(ApiPublicBaseModel):
    super_hero_public_id: str
    power: str
    info_text: str

    @root_validator(pre=True)
    def map_pascal_case_keys(cls, values: Dict[str, Any]) -> Dict[str, Any]:
        # 逐个映射大驼峰键到小驼峰键
        if 'SuperHeroPublicId' in values:
            values['superHeroPublicId'] = values.pop('SuperHeroPublicId')
        if 'Power' in values:
            values['power'] = values.pop('Power')
        if 'InfoText' in values:
            values['infoText'] = values.pop('InfoText')
        return values

这种方式适合字段较少的场景,缺点是需要手动维护所有可能的大驼峰键映射。


内容的提问来源于stack exchange,提问作者error404

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 20:13:13