返回

Pydantic 1 到 2 迁移指南:解决 field_validator 问题

python

从 Pydantic 1 迁移到 Pydantic 2:使用 always=True 解决 field_validator 问题

背景

Pydantic 是一款流行的数据验证库,在 Python 开发中广泛使用。从 Pydantic 1 迁移到 Pydantic 2 时,某些功能可能需要进行调整才能按预期工作。本文将讨论如何解决 field_validator 未按预期工作的问题。

问题

在 Pydantic 1 中,即使 endpoint 字段不存在于请求有效负载中,check_endpoint 验证器方法也会执行。然而,在 Pydantic 2 中,该方法仅在字段存在于有效负载中时才执行。

解决方案

要使 Pydantic 2 中的 check_endpoint 方法的行为与 Pydantic 1 中相同,可以使用 always=True 参数。此参数强制在任何情况下都执行验证器,即使字段不存在于有效负载中。

代码示例

修改后的 Pydantic 2 代码如下:

from pydantic import BaseModel, validator

class Destination(BaseModel):
    destination_type: DestinationType
    topic: Optional[str] = None
    request: RequestType = None
    endpoint: Optional[str] = None

    @field_validator("endpoint", mode='before', always=True)
    @classmethod
    def check_endpoint(cls, value, info: ValidationInfo):
        # coding logic

结论

通过添加 always=True 参数,即使 endpoint 字段不存在于请求有效负载中,check_endpoint 方法也会执行,这与 Pydantic 1 中的行为一致。

常见问题解答

  • 为什么需要在 Pydantic 2 中使用 always=True 参数?

    • 因为在 Pydantic 2 中,默认情况下,field_validator 仅在字段存在于有效负载中时才会执行。
  • 是否可以同时使用 alwaysallow_none 参数?

    • 是的,可以同时使用这两个参数。always 参数确保验证器总是执行,而 allow_none 参数允许该字段为 None
  • always 参数会影响性能吗?

    • 是的,always 参数会稍微降低性能,因为即使字段不存在于有效负载中,验证器也会执行。
  • 是否还有其他方法可以解决这个问题?

    • 是的,另一种方法是使用 model.update() 方法将缺失的字段手动添加到有效负载中。
  • Pydantic 3 中是否对 field_validator 进行了任何更改?

    • 在 Pydantic 3 中,field_validator 的行为与 Pydantic 2 相同。