Pydantic V2 @field_validator未被执行

0 投票
1 回答
55 浏览
提问于 2025-04-14 15:48

我尝试用下面这个 Pydantic (V2) 模型来解析和验证一个 CSV 文件。

from typing import Optional
from pydantic import BaseModel, field_validator
    
class PydanticProduct(BaseModel):
    fid: Optional[float]
    water: Optional[float]

    class ConfigDict:
        from_attributes = True

    @field_validator('fid', 'water',  mode='before')
    def check_empty_fields(cls, value) -> float:
        if value == '':
            return None
        try:
            float_value = float(value)
        except ValueError:
            raise ValueError("Unable to parse string as a number. Please provide a valid number.")
        return float_value

如果 CSV 文件的内容是这样的

fid,water
1.0,81.3
1.25,26.3
3.0,31.5

那么字段会正确地从字符串转换为浮点数。

但是,如果 CSV 文件的内容有空字符串的话

fid,water
1.0,
,26.3
3.0,31.5

我就会遇到以下错误

输入应该是一个有效的数字,无法将字符串解析为数字 [类型=float_parsing, 输入值='', 输入类型=str]

我尝试使用 @field_validatormode="before",但问题是验证没有被执行。

此外,我还注意到,即使没有错误(也就是没有空字符串的情况),验证也没有被执行。

1 个回答

1

来自 字段验证器文档

关于验证器,有几点需要注意:

  • @field_validators 是“类方法”,这意味着它们接收到的第一个参数是 UserModel 类,而不是 UserModel 的一个实例。我们建议在 @field_validator 装饰器下面使用 @classmethod 装饰器,以便进行正确的类型检查。

所以你需要添加缺失的 @classmethod 装饰器。

from typing import Optional
from pydantic import BaseModel, field_validator
    
class PydanticProduct(BaseModel):
    fid: Optional[float]
    water: Optional[float]

    class ConfigDict:
        from_attributes = True

    @field_validator('fid', 'water',  mode='before')
    @classmethod
    def check_empty_fields(cls, value) -> float:
        if value == '':
            return None
        try:
            float_value = float(value)
        except ValueError:
            raise ValueError("Unable to parse string as a number. Please provide a valid number.")
        return float_value

撰写回答