Collections & Mappings
Pydantic provides extensive support for validating aggregate data structures like lists, sets, tuples, and dictionaries. You can enforce constraints on the collection itself (such as length) as well as on the individual items within it.
Handling Top-Level Collections
When your data is a single collection rather than a set of fields, use RootModel. This allows you to treat a list or dictionary as the primary value of the model, accessible via the .root attribute.
from pydantic import RootModel
class UserList(RootModel):
root: list[str]
# Initialize with a list directly
users = UserList(['alice', 'bob'])
print(users.root)
# > ['alice', 'bob']
# Validation still applies to the items
from pydantic import ValidationError
try:
UserList(['alice', 123])
except ValidationError as e:
print(e.errors())
Constraining Collection Size
The preferred way to add constraints like min_length or max_length to a collection is using Annotated with Field. This pattern is recommended over legacy constrained types for better compatibility with static analysis tools.
from typing import Annotated
from pydantic import BaseModel, Field
class Gallery(BaseModel):
# A list that must have between 1 and 5 items
tags: Annotated[list[str], Field(min_length=1, max_length=5)]
# A dictionary with size constraints
metadata: Annotated[dict[str, str], Field(max_length=10)]
# Valid
g = Gallery(tags=['nature'], metadata={'author': 'pydantic'})
Legacy Constrained Types
Pydantic provides convenience functions like conlist, conset, and confrozenset which return Annotated types with length constraints.
from pydantic import BaseModel, conlist, conset
class LegacyModel(BaseModel):
# Equivalent to Annotated[list[int], Field(max_length=10)]
scores: conlist(int, max_length=10) = []
# Sets automatically handle uniqueness and support length constraints
unique_ids: conset(int, min_length=1)
[!WARNING] The
unique_itemsparameter forconlistwas removed in Pydantic V2. Usesetorconsetif you require unique items.
Item-Level Validation Control
You can control how Pydantic handles validation errors for individual items within a collection using specialized annotations found in pydantic.types.
Skipping Invalid Items with OnErrorOmit
Use OnErrorOmit to silently discard items that fail validation instead of raising a ValidationError for the entire collection. This is useful for cleaning "dirty" data.
from pydantic import BaseModel, OnErrorOmit
class DataCleaner(BaseModel):
# Only valid integers will be kept in the list
numbers: list[OnErrorOmit[int]]
m = DataCleaner(numbers=[1, 'invalid', 2, 3.5, '4'])
# 3.5 is coerced to 3, '4' to 4, 'invalid' is omitted
print(m.numbers)
# > [1, 2, 3, 4]
Performance Optimization with FailFast
For large collections where you only need to know if the data is valid or not, FailFast stops validation at the first error encountered, improving performance by avoiding unnecessary checks on subsequent items.
from typing import Annotated
from pydantic import BaseModel, FailFast, ValidationError
class LargeBatch(BaseModel):
data: Annotated[list[int], FailFast()]
try:
# Validation stops at 'a', ignoring the rest of the list
LargeBatch(data=[1, 2, 'a', 4, 5, 'b'])
except ValidationError as e:
# Only the first error is reported
print(len(e.errors()))
# > 1
Validating JSON-Encoded Strings
The Json type allows you to validate strings that contain JSON-encoded data. Pydantic will parse the string and then validate the resulting object against the parametrized type.
from pydantic import BaseModel, Json
class WebhookPayload(BaseModel):
# Expects a JSON string that parses into a list of strings
event_ids: Json[list[str]]
# Input is a string, but the field becomes a list[str]
payload = WebhookPayload(event_ids='["evt_1", "evt_2"]')
print(payload.event_ids)
# > ['evt_1', 'evt_2']
Troubleshooting
RootModeland Extra Fields:RootModeldoes not supportmodel_config['extra']. If you need to handle extra data, use a standardBaseModel.- Static Analysis: If your IDE does not recognize the types returned by
conlistorconset, switch to theAnnotated[list[T], Field(...)]syntax. - ImportString Defaults: If you use
ImportStringwith a string default, you must setvalidate_default=Truein theFielddefinition for the string to be evaluated and imported automatically.