如何使用Pydantic validator校验数据?附自定义校验代码错误排查
Pydantic常用数据校验与清洗技术 + 代码问题排查
一、Pydantic常用数据校验清洗技术
- 基础类型校验:直接在字段上声明类型(如
str/int/datetime等),Pydantic会自动完成类型转换和合法性校验,无需手动写基础判断逻辑 - 自定义校验器:通过
@validator装饰器实现单字段/多字段的自定义规则校验、值标准化清洗,支持配置校验执行顺序、跨字段关联校验等 - 可选字段与默认值:配合
Optional类型、default参数实现非必填字段的兼容处理 - 复杂结构校验:原生支持嵌套模型、列表、字典等复杂数据结构的递归校验
- 内置字段约束:可通过
Field参数快速配置数字范围(gt/lt)、字符串长度(min_length/max_length)、正则匹配(regex)等规则,无需手写校验逻辑 - 自动序列化:校验通过后可直接输出标准化的字典、JSON格式数据,完成数据清洗落地
二、提交代码的错误点排查
name字段校验逻辑与命名不符:函数名name_must_contain_space语义是要求姓名必须包含空格,但实际逻辑仅校验字符范围,没有判断是否存在空格的逻辑,命名语义不匹配age字段校验逻辑完全冗余且有bug:你已经将age声明为int类型,Pydantic会自动完成类型转换和校验,不需要手动判断;且if not (int(v))逻辑会误判合法值0为不合法,同时抛出的AttributeError不是Pydantic可识别的校验异常类型,校验失败时无法被正常捕获streetadr字段校验逻辑失效:if '' not in v的判断永远为假(空字符串属于任何字符串的子串),整个校验条件永远不会触发,等于未做校验;且v.isalnum()的判断逻辑有误,合法地址中包含空格时会被误判为不合法- 缺少校验异常捕获逻辑:代码未捕获
ValidationError,一旦传入非法数据会直接崩溃退出,生产环境无法正常处理异常场景
三、修正后的参考代码
from pydantic import BaseModel, ValidationError, validator class UserModel(BaseModel): name: str age: int streetadr: str @validator('name') def name_only_letters_and_space(cls, v): # 优化校验逻辑,用集合判断替代遍历,性能更高 allowed_chars = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ') if not set(v).issubset(allowed_chars): raise ValueError('名称只能包含英文字母和空格') # 若需要强制要求姓名包含空格可补充以下逻辑 # if ' ' not in v: # raise ValueError('名称必须包含空格') return v.title() @validator('streetadr') def street_address_valid(cls, v): # 明确允许地址包含的字符:字母、数字、空格 allowed_chars = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ') if not set(v).issubset(allowed_chars): raise ValueError('地址只能包含英文字母、数字和空格') return v class GroupModel(BaseModel): users: UserModel if __name__ == '__main__': try: u = GroupModel(users={'name':"james Wash", 'age':"23", 'streetadr':'2333 Sabrina Dr'}) print(u.json(indent=2, ensure_ascii=False)) except ValidationError as e: print(f"校验失败:{e.errors()}")
内容的提问来源于stack exchange,提问作者Terr McCoy
相关产品推荐
相关产品推荐

