Best practices

Practical guidance for 0.6.0 Core, ORM, and rejection-platform usage.

Prefer projection models

Validate read models (the columns you select), not full persistence entities. Smaller models are faster to validate and clearer contracts.

Choose rejection policy deliberately

Situation

Policy

Tests / strict APIs

raise (default)

ETL / audit of bad rows

collect

Best-effort streaming

skip

Metrics / conditional stop

callback

Durable bad-row handoff

quarantine

Ops visibility without retention

log

Remember: under skip / log / receipt-only quarantine, has_rejections may be true while rejected is empty. See Rejection policies.

Know your pushdown setting

Default use_sqlrules=True filters in SQL. Use False when you need Python-side rejected rows. See SQLRules pushdown.

Always context-manage streams

with rowguard.stream(...) as stream:
    for model in stream:
        ...

async with rowguard.astream(...) as stream:
    async for model in stream:
        ...

Bare iteration is weaker under async cancellation.

Keep async models lean

Pydantic runs on the event loop. Heavy validators can stall other coroutines. See Async.

Pass exactly one execution handle

Provide session= or connection=, never both.

Inspect plans in tests

Use compile_plan(...) to assert pushdown / statement shape without hitting the database.