Skip to content

0.16.0

Choose a tag to compare

@igorbenav igorbenav released this 25 Aug 02:12
· 39 commits to main since this release
8718cf8

0.16.0 Summary

Added

  • Enhanced Create Method Return Types by @doubledare704
    • Added schema_to_select parameter to create method for selecting specific columns
    • Added return_as_model parameter to return Pydantic models instead of SQLAlchemy instances
  • 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 NotImplementedError with sqlalchemy-utils types
    • Documentation references for python_type attribute requirement

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

⚠️ None - This release maintains full backward compatibility with 0.15.x

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_select Parameter: Specify which columns to return from the created record
  • return_as_model Parameter: 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_type attribute 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

@doubledare704 continues their excellent contributions to the project

Full Changelog: v0.15.12...v0.16.0