Pydantic 验证错误:输入应为有效的字典或实例

Pydantic Validation error: Input should be a valid dictionary or instance

提问人:PepeLoperena 提问时间:11/7/2023 最后编辑:PepeLoperena 更新时间:11/10/2023 访问量:474

问:

我正在尝试验证纬度和经度:

from pydantic import BaseModel, Field
from pydantic.dataclasses import dataclass

@dataclass(frozen=True)
class Location(BaseModel):
    longitude: float = Field(None, ge=-180, le=180)
    latitude: float = Field(None, ge=-90, le=90)


Location(longitude=1.0, latitude=1.0)

当我在本地运行它时,我收到以下错误:

Input should be a valid dictionary or instance of Location [type=model_type, input_value=ArgsKwargs((), {'longitud...: 1.0, 'latitude': 1.0}), input_type=ArgsKwargs]
    For further information visit https://errors.pydantic.dev/2.4/v/model_type

我已经尝试遵循错误给出的 Pydantic 文档,但不幸的是不清楚,并没有真正提供有关更改内容和不同做法的任何信息。

我还尝试创建一个 Python 字典,看看是否可以解决错误,但它仍然给出了相同的错误。

老实说,我不知道下一步该做什么以及如何解决这个问题,因为我已经在多个文件中对其进行了测试(包括在同一文件中,以确保它与任何导入无关)。

知道为什么会发生错误吗?

更新

如果没有 在同一文件中运行数据类的实例,它就可以工作。现在,我正在创建不同的单元测试来测试是否正常工作。请检查以下代码片段:(BaseModel)validators

创建单元测试并运行此类测试时:

 def test_when_location_is_not_in_range_then_print_exception(self):
        invalid_location = Location(latitude=200.0, longitude=300.0)

        with self.assertRaises(ValueError) as context:
            location = Location(latitude=invalid_location.latitude, longitude=invalid_location.longitude)

        self.assertEqual(
            str(context.exception), "Location is out of range", "Expected exception message: 'Location is out of range'"
        )

在运行测试之前,将显示一条警告:Unexpected Argument

运行测试后,将出现一个新错误:

longitude
  Input should be less than or equal to 180 [type=less_than_equal, input_value=300.0, input_type=float]
    For further information visit https://errors.pydantic.dev/2.4/v/less_than_equal
latitude

  Input should be less than or equal to 90 [type=less_than_equal, input_value=200.0, input_type=float]
    For further information visit https://errors.pydantic.dev/2.4/v/less_than_equal

之前遇到的错误不再出现。

Python 验证 pydantic

评论

2赞 Johan 11/7/2023
你能展示你的陈述吗?尝试运行代码,它对我有用。import
0赞 Paweł Rubin 11/7/2023
它也适用于我。
0赞 PepeLoperena 11/7/2023
这些是 pydantic import BaseModel 中使用的 import 语句,来自 pydantic.dataclasses 的字段 import dataclass

答:

2赞 Paweł Rubin 11/7/2023 #1

我猜你正在使用 .dataclasspydantic.dataclasses

在这种情况下,不要继承自BaseModel

from pydantic import Field
from pydantic.dataclasses import dataclass


@dataclass(frozen=True)
class Location:
    longitude: float = Field(None, ge=-180, le=180)
    latitude: float = Field(None, ge=-90, le=90)


Location(longitude=1.0, latitude=1.0)

更多信息,请访问 https://docs.pydantic.dev/latest/concepts/dataclasses/


关于您的问题的更新 - 验证错误来自

    invalid_location = Location(latitude=200.0, longitude=300.0)

您限制了 and 属性的有效值范围,因此,当提供的值不符合这些要求时,会出现错误。latitudelongitude

评论

0赞 PepeLoperena 11/7/2023
当我在同一文件中进行测试时,这有效。每当我尝试在不同的文件(例如测试文件)中构造数据类时,我都会收到以下错误:def setUp(self) -> None: address = Address( original_address="test", accuracy=Accuracy.ROOFTOP, location=Location(longitude=1.0, latitude=1.0),) Unexpected Argument
0赞 PepeLoperena 11/7/2023
即使我运行一个简单的单元测试,我也会回到同样的错误,这是主要问题中的错误。Input should be a dictionary or an instance of Location [type=dataclass_type, input_value=Location(longitude=1.0, latitude=1.0), input_type=Location]
0赞 Paweł Rubin 11/7/2023
由于您提到的错误涉及不同的模型(),那么也许您也应该更改其定义。Address
0赞 PepeLoperena 11/7/2023
即使我更改了相同问题的定义,也出现了。我只是更改了创建一个对象,但仍然出现Addressdef setUp()LocationUnexpected Argument
0赞 Paweł Rubin 11/7/2023
请在主要问题中包括一个最小可重复的例子。