Skip to content

prefer-declarative-batch-validation

Validate a homogeneous Pydantic batch with a declared collection contract.

Why

Per-record validation comprehensions and catch/log/drop builders spread a collection contract across repeated model calls and mutable error-handling scaffolding. A named collection schema makes the batch's error policy explicit.

Fix

Use class_row(Model) for unchanged Psycopg model rows, or a named RootModel[list[Model]] for collection validation. Declare whether invalid records reject the batch or are intentionally omitted (for example with OnErrorOmit). Preserve required logging and rejection reports.

Examples

Before — flagged Declare collection validation once
app/batches.py
from pydantic import BaseModel
class Item(BaseModel):
value: int
def load(rows: list[object]):
return [Item.model_validate(row) for row in rows]
After — preferred A named collection schema owns the batch
app/batches.py
from pydantic import BaseModel, RootModel
class Item(BaseModel):
value: int
class Items(RootModel[list[Item]]):
pass
def load(rows: list[object]):
return Items.model_validate(rows).root