Python Pydantic 在对象列表中验证 ID 唯一性

2 投票
1 回答
52 浏览
提问于 2025-04-13 01:35

给出一个简单的例子

from pydantic import BaseModel

class UserModel(BaseModel):
    name: str
    id: int

data : List[UserModel] = [{id:1,name:'bob'},{id:1,name:'mary}]

我该如何使用pydantic来验证数据,确保列表中的id不能重复呢?

1 个回答

3

首先,你的数据格式不对,键(也就是数据的名字)必须是字符串,像这样:

[{"id": 1, "name": "bob"}, {"id": 1, "name": "mary"}]

你可以使用 AfterValidation 和一个叫 TypeAdapter 的东西。

from typing import Annotated
from pydantic import AfterValidator, BaseModel, TypeAdapter


class UserModel(BaseModel):
    id: int
    name: str


def check_uniqueness(data: list[UserModel]):
    ids = [user.id for user in data]
    if len(ids) != len(set(ids)):
        raise ValueError("Ids are not unique")
    return data


unique_users = TypeAdapter(Annotated[list[UserModel], AfterValidator(check_uniqueness)])
data1 = [{"id": 1, "name": "bob"}, {"id": 2, "name": "mary"}]
data2 = [{"id": 1, "name": "bob"}, {"id": 1, "name": "mary"}]
print(unique_users.validate_python(data1))
try:
    print(unique_users.validate_python(data2))
except ValueError as e:
    print(e)

输出结果:

[UserModel(id=1, name='bob'), UserModel(id=2, name='mary')]
1 validation error for function-after[check_uniqueness(), list[UserModel]]
  Value error, Ids are not unique [type=value_error, input_value=[{'id': 1, 'name': 'bob'}...id': 1, 'name': 'mary'}], input_type=list]
    For further information visit https://errors.pydantic.dev/2.6/v/value_error

你还可以进一步改进 check_uniqueness 这个函数,让它告诉用户哪些键是重复的。

撰写回答