sqlmodel
SQLModel for FastAPI
Comprehensive skill for building database-driven FastAPI applications with SQLModel, PostgreSQL, and SQLAlchemy.
Quick Start
Basic Setup
# Install dependencies
pip install sqlmodel psycopg2-binary alembic pytest
# Create database models
from sqlmodel import SQLModel, Field, create_engine
from typing import Optional
class User(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
username: str = Field(unique=True, index=True)
email: str = Field(unique=True, index=True)
# Create engine and tables
engine = create_engine("postgresql://user:pass@localhost/db")
SQLModel.metadata.create_all(engine)
# Use in FastAPI
from fastapi import FastAPI, Depends
from sqlmodel import Session
app = FastAPI()
def get_session():
with Session(engine) as session:
yield session
@app.post("/users")
def create_user(user: User, session: Session = Depends(get_session)):
session.add(user)
session.commit()
session.refresh(user)
return user
Reference Documentation
This skill includes comprehensive reference files organized by topic. Read the relevant file based on your needs:
Core Topics
-
models.md - SQLModel basics, field types, constraints, table configuration, request/response models, computed fields, JSON fields, UUID keys, composite primary keys
-
relationships.md - One-to-many, one-to-one, many-to-many relationships, cascade deletes, self-referential relationships, lazy vs eager loading, association object pattern
-
sessions.md - Database engine setup, session management, FastAPI dependency injection, connection pooling, async sessions, multiple databases, transaction control
-
crud.md - Create, read, update, delete operations, bulk operations, upsert patterns, soft deletes, transaction patterns, FastAPI endpoint integration
-
queries.md - Where clauses, ordering, pagination, aggregations, joins, subqueries, dynamic filtering, full-text search, JSON queries, window functions, exists queries
Advanced Topics
-
migrations.md - Alembic setup and configuration, creating and applying migrations, migration operations, data migrations, branching and merging, production workflow, FastAPI integration
-
testing.md - Test database setup, FastAPI TestClient integration, testing CRUD operations, testing relationships, fixtures, parametrized tests, database isolation, coverage
-
performance.md - Connection pooling optimization, query optimization, N+1 problem solutions, indexing strategies, bulk operations, pagination best practices, caching, read replicas, batch processing
-
integration.md - FastAPI project structure, application lifespan, router implementation, custom dependencies, response models with relationships, error handling, middleware, background tasks, WebSocket integration
-
advanced.md - Transaction management, nested transactions, cascading deletes, soft deletes, event listeners, optimistic locking, database constraints, custom field types, security best practices, monitoring and logging
Common Workflows
Creating a New Model
- Define the model in your models file
- Add relationships if needed
- Create request/response schemas
- Generate migration:
alembic revision --autogenerate -m "Add model" - Review and apply migration:
alembic upgrade head - Implement CRUD functions
- Create API endpoints
- Write tests
Setting Up Database
- Install dependencies:
pip install sqlmodel psycopg2-binary alembic - Create database configuration in
database.py - Define models in
models.py - Initialize Alembic:
alembic init alembic - Configure Alembic for SQLModel (see migrations.md)
- Create initial migration
- Set up dependency injection for sessions
Optimizing Performance
- Add indexes on frequently queried columns (see models.md)
- Use eager loading for relationships (see relationships.md)
- Configure connection pooling (see sessions.md)
- Implement pagination (see queries.md)
- Use bulk operations for multiple inserts/updates (see crud.md)
- Add query caching if needed (see performance.md)
Adding Relationships
- Define foreign key in child model
- Add
Relationshipfield in both models - Use
back_populatesto link them - For many-to-many, create link table
- Configure cascade behavior if needed (see relationships.md)
- Update migrations
- Test relationship loading
When to Use Each Reference
- Starting a new project? Read: sessions.md → models.md → integration.md
- Need relationships? Read: relationships.md
- Writing queries? Read: queries.md
- Performance issues? Read: performance.md → queries.md
- Setting up testing? Read: testing.md
- Database migrations? Read: migrations.md
- Building CRUD endpoints? Read: crud.md → integration.md
- Advanced features? Read: advanced.md
Best Practices Summary
Model Design
- Use
Optional[int]withdefault=Nonefor auto-increment primary keys - Add indexes to foreign keys and frequently queried fields
- Use enums for status/category fields
- Separate table models from request/response models
- Use mixins for common fields (created_at, updated_at)
Session Management
- Always use dependency injection in FastAPI endpoints
- Use context managers (
with Session()) for manual sessions - Configure connection pooling for production
- Set
pool_pre_ping=Trueto handle stale connections
Queries
- Use eager loading to avoid N+1 queries
- Add appropriate indexes before querying large datasets
- Use cursor-based pagination for large result sets
- Use
select()for all queries instead of legacy query API
Migrations
- Always review auto-generated migrations before applying
- Test migrations locally before production
- Make migrations reversible (implement both upgrade and downgrade)
- Use separate migrations for schema and data changes
Testing
- Use SQLite in-memory database for tests
- Use fixtures for test data
- Override FastAPI dependencies in tests
- Test both success and failure cases
Performance
- Index foreign keys and frequently queried columns
- Use bulk operations for multiple inserts/updates
- Configure appropriate pool sizes based on load
- Monitor slow queries and optimize them
Security
- Never use string formatting for queries (use parameterized queries)
- Hash passwords with bcrypt or similar
- Validate all user input with Pydantic
- Use environment variables for database credentials
- Handle database errors gracefully without exposing internals
Example Project Structure
app/
├── __init__.py
├── main.py # FastAPI app with lifespan
├── database.py # Engine and session setup
├── models.py # SQLModel definitions
├── crud.py # CRUD operations
├── dependencies.py # FastAPI dependencies
├── config.py # Settings with pydantic-settings
├── routers/
│ ├── __init__.py
│ ├── users.py
│ └── posts.py
└── tests/
├── __init__.py
├── conftest.py # Test fixtures
├── test_users.py
└── test_posts.py
alembic/
├── versions/
│ └── *.py # Migration files
├── env.py # Alembic configuration
└── script.py.mako
.env # Environment variables
alembic.ini # Alembic config
pyproject.toml # Dependencies
Troubleshooting
Common Issues
Import errors with SQLModel models:
- Ensure all models are imported in
alembic/env.py - Import models before calling
SQLModel.metadata.create_all()
N+1 query problems:
- Use
selectinload()orjoinedload()for relationships - Check query logs with
echo=Trueon engine
Connection pool exhausted:
- Increase
pool_sizeandmax_overflow - Ensure sessions are properly closed (use context managers)
- Check for long-running transactions
Migration conflicts:
- Use
alembic headsto check for multiple heads - Merge branches with
alembic merge - Resolve conflicts manually in migration files
Slow queries:
- Add indexes on queried columns
- Use
EXPLAIN ANALYZEto check query plan - Consider using read replicas for read-heavy workloads
Additional Resources
For detailed information on specific topics, refer to the reference files in the references/ directory. Each file contains comprehensive examples and patterns for that specific area.
More from jr2804/prompts
python-ultimate
>-
34output-quality
Detect and eliminate generic, low-quality "AI slop" patterns in natural language, code, and design. Use when REVIEWING existing content (text, code, or visual designs) for quality issues, cleaning up generic patterns, or establishing quality standards. Focuses on pattern detection—not content creation.
9coding-discipline
Language-agnostic behavioral guidelines to reduce common LLM coding mistakes. Use for ANY coding task (all languages) to avoid overcomplication, make surgical changes, surface assumptions before coding, and define verifiable success criteria. Applies behavioral rigor—separate from language-specific technical standards.
9cli-vstash
Local document memory with semantic search for AI-assisted workflows. Use when managing project documentation, codebases, or research papers that need persistent memory across sessions. Triggers on: vstash add/search/ask commands, document ingestion, semantic search, RAG pipelines, local knowledge bases, or configuring vstash for personal projects.
5mcp-vstash
MCP server integration for vstash document memory. Use when configuring Claude Desktop or other MCP-compatible AI assistants with persistent document memory, setting up vstash MCP tools for semantic search and Q&A, or integrating vstash with AI assistant workflows via Model Context Protocol.
5code-deduplication
Pre-write workflow to prevent semantic code duplication. Use BEFORE creating new utility functions, shared modules, or helper code to verify equivalent capabilities don't already exist in the codebase. Requires maintaining CODE_INDEX.md as a capability index organized by purpose (not file location).
5