
使用字典初始化 Pydantic 模型时出现 "Input should be a valid string" 等错误,通常并非字段类型声明问题,而是自定义 @field_validator 未显式返回输入值所致——Pydantic 要求验证器必须返回(或重新赋值后的)有效值,否则字段被设为 None,触发后续类型校验失败。
使用字典初始化 pydantic 模型时出现 `"input should be a valid string"` 等错误,通常并非字段类型声明问题,而是自定义 `@field_validator` 未显式返回输入值所致——pydantic 要求验证器必须返回(或重新赋值后的)有效值,否则字段被设为 `none`,触发后续类型校验失败。
在你的代码中,Schema 类继承自 Beanie 的 Document,并使用了 Pydantic v2 的 field_validator(注意:你未在问题中贴出验证器实现,但答案明确指出“forgot to set return values in my validators”)。这是典型的验证器陷阱:Pydantic v2 中,@field_validator 必须显式 return 值,否则函数默认返回 None,导致对应字段被赋值为 None,进而触发严格类型检查(如 str 字段收到 None → 报 string_type 错误;int 字段收到 None → 报 int_type 错误)。
✅ 正确的验证器写法示例:
from pydantic import field_validator
class Schema(Document):
model_config = ConfigDict(extra='forbid')
name: str = Field(alias='name')
description: str = Field(alias='description')
date: int = Field(alias='date')
@field_validator('name', 'description')
@classmethod
def validate_non_empty_string(cls, v):
if not isinstance(v, str) or not v.strip():
raise ValueError('Field must be a non-empty string')
return v # ✅ 必须返回处理后的值!
@field_validator('date')
@classmethod
def validate_positive_year(cls, v):
if not isinstance(v, int) or v = 1900)')
return v # ✅ 同样必须返回!
⚠️ 常见错误写法(导致 None 赋值):
# ❌ 错误:没有 return 语句 → 函数返回 None
@field_validator('name')
@classmethod
def validate_name(cls, v):
if not v:
raise ValueError('Name cannot be empty')
# 缺少 return v ← 这是根本原因!
# ❌ 错误:条件分支遗漏 return
@field_validator('date')
@classmethod
def validate_date(cls, v):
if isinstance(v, str):
v = int(v)
# 如果 v 原本就是 int,此处无 return → 返回 None
? 调试建议:
- 在验证器中添加
print(f"Validating {field}: {v!r}")和print(f"Returning {v!r}"),确认是否进入验证器及返回值; - 使用
pydantic.BaseModel简化复现问题(排除 Beanie 干扰); - 检查所有
@field_validator是否 100% 覆盖所有执行路径并return。
? 总结:Pydantic v2 的验证器是纯函数式设计——它不修改原地值,只通过 return 提供新值。任何遗漏 return 的验证器都会使字段变为 None,从而在模型初始化阶段触发基础类型校验失败。这不是配置或别名问题,而是验证逻辑的强制契约。










