Bugfix release for the CRUD write paths, route registration, and
packaging. All fixes are covered by regression tests
(tests/test_write_path_regressions.py).
- Body-schema leak between viewsets (critical).
register()used to mutate__annotations__of the shared class-level CRUD functions, so in any process with two or more viewsets everyPOST/PUT/PATCHendpoint validated against the last registered viewset's schema. Handlers are now cloned per instance before the body annotation is patched. - PATCH is truly partial. The PATCH body is validated against an
auto-generated all-optional variant of the
response_model(<Schema>Patch). Previously a partial PATCH body failed validation with422whenever the schema had required fields. - PATCH honors explicit
null. Explicitly sent JSONnullnow clears a nullable column instead of being silently dropped. - Pagination validated. Negative
limit/offsetare rejected with422;limitis capped at 10000. Defaults (limit=10,offset=0) are documented. - Filters in OpenAPI. Whitelisted
ListConfig.filtersfields and their__opvariants (__gte,__in, …) are advertised in the generated OpenAPI schema and Swagger UI.
- PUT no longer nulls columns absent from the schema. Only fields
explicitly present in the payload are written; the primary key is
never overwritten. Previously
PUTset every non-schema column toNULL(data loss). - Create strips an explicit
NULLprimary key. Schemas withid: Optional[int] = Noneno longer breakPOSTon Tortoise (id is non nullable field, but null was passed) and no longer sendNULLfor the PK on backends like PostgreSQL. - Integrity violations return
409 Conflictwith a sanitized message ("Integrity error: a database constraint was violated"). Raw SQL, parameters and driver internals are no longer exposed in response bodies; generic adapter errors likewise use static messages.
- Base install is now truly ORM-agnostic:
SQLAlchemyanduvicornwere removed from core dependencies. The package imports cleanly without SQLAlchemy installed. fastapi-viewsets[sqlalchemy]now installsSQLAlchemy[asyncio], which includesgreenlet— async sessions work out of the box.
- Integrity violations:
400→409(message no longer contains raw SQL). - PATCH with explicit
nullwritesNULL(previously ignored). - PUT no longer clears fields/columns missing from the payload.
pip install fastapi-viewsetsno longer pulls SQLAlchemy/uvicorn — usefastapi-viewsets[sqlalchemy]and installuvicornto run apps.