Pydantic 通用基础模型验证错误

问题描述 投票:0回答:1

Pydantic Generic BaseModels 在验证 python 实例时意外失败,但在验证与字典相同的数据时成功。

Python:3.11.8 派丹蒂克:2.7.1

这是通用模型:

from typing import Generic, TypeVar

from pydantic import BaseModel

U = TypeVar("U")


class M1(BaseModel, Generic[U]):
    a: list[U]
    b: list[U]


class M2(BaseModel):
    a: str
    m1: M1[int]

它在验证原始字典时有效:

m2 = M2.model_validate(
    {
        "a": "s",
        "m1": {
            "a": [1],
            "b": [2]
        }
    }
)

但是,当使用 python 类型时它不起作用:

m2 = M2(
    a="s",
    m1=M1(
        a=[1],
        b=[2]
    )
)  # fails :(

有趣的是,以下也失败了:

m2 = M2.model_validate(
    dict(
        a="s",
        m1=M1(
            a=[1],
            b=[2]
        )
    )
)
python pydantic
1个回答
0
投票

这完全是预期的行为。由于

M1
是泛型类型,因此需要使用相应的要使用的类型进行声明。如果我复制并粘贴您的示例:

m2 = M2(
    a="s",
    m1=M1(
        a=[1],
        b=[2]
    )
)  # fails :(

它失败了:

ValidationError: 1 validation error for M2
m1
  Input should be a valid dictionary or instance of M1[int] [type=model_type, input_value=M1(a=[1], b=[2]), input_type=M1]
    For further information visit https://errors.pydantic.dev/2.7/v/model_type

这里重要的细节是“

M1[int]
的实例”。因此,当仅实例化
M1
而不声明其类型时,实例的类型为
M1
,与
M1[int]
类型不同。然而
M2
明确期望
M1[int]
,因此以下内容可以正常工作:

m2 = M2(
    a="s",
    m1=M1[int](
        a=[1],
        b=[2]
    )
)  # validates correctly

当你只是从字典中验证时,它工作得很好,因为 Pydantic 依赖于

M2.m1
中声明的默认类型,这又是
M1[int]

现在的问题是你想要实现什么样的行为。那么

M1
应该允许哪些类型呢?也许你必须使用类型的联合或类似的......

我希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.