Session Management
The async session factory pattern, connection pooling configuration, and session lifecycle.
Status: Extracted
Purpose: Session Factory pattern, async database operations, and connection pooling.
Session Factory Pattern
Rationale
- Centralizes database engine and session creation
- Enables efficient connection pooling
- Provides single point of configuration for database settings
- Supports dependency injection for testability
- Required foundation for Unit of Work pattern
Implementation
Location: infrastructure/database/session.py
Pattern:
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker, create_async_engine
def create_session_factory(config: DatabaseConfig) -> async_sessionmaker[AsyncSession]:
"""
Create an async session factory for database connections.
This function creates an AsyncEngine and returns an async_sessionmaker
that can be used to create database sessions. The factory manages
connection pooling and should be created once at application startup.
"""
engine: AsyncEngine = create_async_engine(
config.database_url,
pool_size=config.pool_size,
max_overflow=config.max_overflow,
pool_timeout=config.pool_timeout,
echo=config.echo,
pool_pre_ping=config.pool_pre_ping,
future=True, # Use SQLAlchemy 2.0 style
)
return async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)Usage
Application Startup:
- Session factory created at application startup
- Stored in
app.state.session_factoryfor dependency access - Uses SQLAlchemy
async_sessionmakerwithAsyncEngine - All database operations use sessions from the factory
Session Creation:
# Get session factory from app state
session_factory = app.state.session_factory
# Create a session
async with session_factory() as session:
# Use session for database operations
result = await session.execute(query)Async Database Operations
Rationale
- Aligns with FastAPI's async model for better performance
- Enables non-blocking I/O for database operations
- Improves concurrency and scalability
- Better resource utilization for I/O-bound operations
- Industry standard for async Python web applications
Implementation
Driver: Uses asyncpg driver instead of psycopg2-binary
Session Type: All database operations use AsyncSession from SQLAlchemy
Pattern:
- Repository interfaces and implementations are async
- Command handlers are async to support async repository calls
- Unit of Work manages async sessions
- All database queries use
awaitfor async execution
Example:
async def get_user_by_id(self, user_id: str) -> User | None:
"""Get user by ID."""
async with self.session_factory() as session:
result = await session.execute(
select(UserModel).where(UserModel.id == user_id)
)
user_model = result.scalar_one_or_none()
return self._to_domain(user_model) if user_model else NoneConnection Pooling
Configuration
Pool Settings:
pool_size: Number of connections to maintain in pool (default: 5)max_overflow: Maximum overflow connections (default: 10)pool_timeout: Timeout for getting connection from pool (default: 30)pool_pre_ping: Test connections before using (default: True)
Benefits:
- Reuses connections for better performance
- Limits concurrent connections to database
- Handles connection failures gracefully
- Reduces connection overhead
Session Lifecycle
Session Creation
- Factory Creation: Session factory created at application startup
- Session Request: Session created from factory when needed
- Transaction Start: Transaction begins when session is used
- Operations: Database operations performed within session
- Commit/Rollback: Transaction committed or rolled back
- Session Close: Session closed and returned to pool
Best Practices
- Use Context Managers: Always use
async withfor session management - Single Transaction: Keep all related operations in one session
- Error Handling: Ensure sessions are closed even on errors
- Connection Pooling: Let factory manage connection pooling
Related Documents
- Migration principles (all stacks) — Tool-agnostic migration rules
- Migration patterns — Alembic — Python / SQLAlchemy workflow
- Migration patterns — Drizzle Kit — TypeScript workflow
- Unit of Work Pattern - Transaction management
- Repository Implementation - Repository patterns
Reference implementation: infrastructure/database/session.py in any FastAPI service.