0.16.0
0.16.0 Summary
Added
- Enhanced Create Method Return Types by @doubledare704
- Added
schema_to_selectparameter tocreatemethod for selecting specific columns - Added
return_as_modelparameter to return Pydantic models instead of SQLAlchemy instances
- Added
- Advanced Sorting Functionality by @doubledare704
- Multi-field sorting support with ascending/descending order control
- Sort parameter integration in CRUD router endpoints
- Flexible sorting syntax:
field1,-field2(ascending/descending)
- Dependency-Based Filtering by @doubledare704
- Runtime filtering using FastAPI dependencies
- Perfect for row-level access control and tenant isolation
- Seamless integration with authentication systems
Improved
- Enhanced Documentation by @arab0v
- Added comprehensive warning about non-native SQLAlchemy column types
- Detailed sorting documentation with examples
- New dependency-based filtering guide
Fixed
- SQLAlchemy Non-Native Column Types Support by @arab0v
- Added guidance for handling
NotImplementedErrorwith sqlalchemy-utils types - Documentation references for
python_typeattribute requirement
- Added guidance for handling
Documentation Updates
- Added Sorting Results Section with comprehensive examples and error handling
- New Dependency-Based Filtering Guide with practical authentication scenarios
- Enhanced Endpoint Documentation with sorting parameter details
- SQLAlchemy Compatibility Warnings for non-native column types
Breaking Changes
Details
Enhanced Create Method with Flexible Return Types
Description
The create method now supports returning data as Pydantic models with selective column fetching, providing more flexibility in API responses and reducing data transfer overhead.
Changes
schema_to_selectParameter: Specify which columns to return from the created recordreturn_as_modelParameter: Return data as a Pydantic model instead of SQLAlchemy instance- Automatic Refresh: Ensures created records are properly refreshed before return
Usage Example
from fastcrud import FastCRUD
from .models.item import Item
from .schemas import ItemCreateSchema, ItemResponseSchema
from .database import session as db
crud_items = FastCRUD(Item)
# Create and return as Pydantic model with selected fields
created_item = await crud_items.create(
db=db,
object=ItemCreateSchema(name="New Item", price=29.99),
schema_to_select=ItemResponseSchema,
return_as_model=True
)Advanced Multi-Field Sorting
Description
FastCRUD now provides comprehensive sorting capabilities with support for multiple fields, mixed sort orders, and automatic integration with existing CRUD endpoints.
Changes
- Multi-Field Sorting: Sort by multiple columns with individual order control
- Flexible Syntax: Use
-prefix for descending order (-price,name) - Error Handling: Automatic validation of column names against model schema
- Router Integration: Seamless sorting in automatically generated endpoints
Usage Examples
Single Field Sorting:
# Sort by name (ascending)
curl 'http://localhost:8000/items?sort=name'
# Sort by price (descending)
curl 'http://localhost:8000/items?sort=-price'Multi-Field Sorting:
# Sort by category ascending, then price descending
curl 'http://localhost:8000/items?sort=category,-price'Combined with Pagination and Filtering:
curl 'http://localhost:8000/items?sort=-created_at&page=1&itemsPerPage=10&category=Electronics'Benefits
- Performance: Optimized SQL generation with proper ORDER BY clauses
- Flexibility: Mix ascending and descending orders as needed
- Validation: Prevents SQL injection and invalid column references
- Integration: Works seamlessly with existing pagination and filtering
Dependency-Based Filtering for Access Control
Description
Introduce runtime filtering based on FastAPI dependencies, enabling sophisticated access control patterns like multi-tenancy and row-level security without manual query modification.
Changes
- Dependency Integration: Use any FastAPI dependency as a filter value
- Runtime Resolution: Filters are resolved at request time
- Access Control: Perfect for implementing tenant isolation
- Flexible Configuration: Works with existing FilterConfig system
Usage Example
from fastapi import Depends, FastAPI
from fastcrud import crud_router, FilterConfig
from .auth import get_current_user, UserInfo
from .database import async_session
from .models import Task
from .schemas import TaskSchema
async def get_user_org_id(user: UserInfo = Depends(get_current_user)):
return user.organization_id
# Automatically filter tasks by user's organization
app = FastAPI()
task_router = crud_router(
session=async_session,
model=Task,
create_schema=TaskSchema,
update_schema=TaskSchema,
path="/tasks",
filter_config=FilterConfig(
organization_id=get_user_org_id, # Resolved per request
),
tags=["tasks"],
)
app.include_router(task_router)Benefits
- Security: Automatic row-level access control
- Simplicity: No manual filter injection required
- Flexibility: Use any dependency (auth, headers, etc.)
- Performance: Filters applied at database level
SQLAlchemy Non-Native Column Types Support
Description
Enhanced documentation and guidance for handling non-native SQLAlchemy column types, particularly those from sqlalchemy-utils, preventing common NotImplementedError issues.
Changes
- Documentation Warning: Clear guidance on
python_typeattribute requirement - Reference Links: Direct links to relevant sqlalchemy-utils discussions
- Prevention Guide: Proactive error prevention for developers
Example Solution
When using sqlalchemy-utils column types:
from sqlalchemy_utils import EmailType
from sqlalchemy import Column
class User(Base):
email = Column(EmailType) # May cause NotImplementedError
# Solution: Add python_type
email = Column(EmailType, python_type=str)What's Changed
- docs: add warning about non-native column types in SQLAlchemy models by @arab0v in #237
- feat: Allow create method to return a Pydantic model by @doubledare704 in #241
- Feat: new query param to make sorting available by @doubledare704 in #231
- feat: add sorting to crud_router by @doubledare704 in #240
- Feature/dependency based filtering by @doubledare704 in #229
- update project version by @igorbenav in #243
@doubledare704 continues their excellent contributions to the project
Full Changelog: v0.15.12...v0.16.0