Python Pydantic validate in a list of objects for uniqueness of id

54 views Asked by At

given a simple example of

from pydantic import BaseModel

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

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

how do i validate with pydantic for data such that id cannot be duplicated in the List?

1

There are 1 answers

0
S.B On

First off, your data is not in a proper format, the keys must be string like:

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

You can use the AfterValidation along with a 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)

output:

[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

You can further improve the check_uniqueness function to report which keys are the same to the user.