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
Relationship field in both models
- Use
back_populates to 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] with default=None for 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=True to 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() or joinedload() for relationships
- Check query logs with
echo=True on engine
Connection pool exhausted:
- Increase
pool_size and max_overflow
- Ensure sessions are properly closed (use context managers)
- Check for long-running transactions
Migration conflicts:
- Use
alembic heads to check for multiple heads
- Merge branches with
alembic merge
- Resolve conflicts manually in migration files
Slow queries:
- Add indexes on queried columns
- Use
EXPLAIN ANALYZE to 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.
1---2name: sqlmodel3description: Comprehensive guide for working with SQLModel, PostgreSQL, and SQLAlchemy in FastAPI projects. Use when working with database operations in FastAPI including: (1) Defining SQLModel models and relationships, (2) Database connection and session management, (3) CRUD operations, (4) Query patterns and filtering, (5) Database migrations with Alembic, (6) Testing with SQLite, (7) Performance optimization and connection pooling, (8) Transaction management and error handling, (9) Advanced features like cascading deletes, soft deletes, and event listeners, (10) FastAPI integration patterns. Covers both basic and advanced database patterns for production-ready FastAPI applications.4---56# SQLModel for FastAPI78Comprehensive skill for building database-driven FastAPI applications with SQLModel, PostgreSQL, and SQLAlchemy.910## Quick Start1112### Basic Setup1314```python15# Install dependencies16pip install sqlmodel psycopg2-binary alembic pytest1718# Create database models19from sqlmodel import SQLModel, Field, create_engine20from typing import Optional2122class User(SQLModel, table=True):23 id: Optional[int] = Field(default=None, primary_key=True)24 username: str = Field(unique=True, index=True)25 email: str = Field(unique=True, index=True)2627# Create engine and tables28engine = create_engine("postgresql://user:pass@localhost/db")29SQLModel.metadata.create_all(engine)3031# Use in FastAPI32from fastapi import FastAPI, Depends33from sqlmodel import Session3435app = FastAPI()3637def get_session():38 with Session(engine) as session:39 yield session4041@app.post("/users")42def create_user(user: User, session: Session = Depends(get_session)):43 session.add(user)44 session.commit()45 session.refresh(user)46 return user47```4849## Reference Documentation5051This skill includes comprehensive reference files organized by topic. Read the relevant file based on your needs:5253### Core Topics5455- **[models.md](references/models.md)** - SQLModel basics, field types, constraints, table configuration, request/response models, computed fields, JSON fields, UUID keys, composite primary keys5657- **[relationships.md](references/relationships.md)** - One-to-many, one-to-one, many-to-many relationships, cascade deletes, self-referential relationships, lazy vs eager loading, association object pattern5859- **[sessions.md](references/sessions.md)** - Database engine setup, session management, FastAPI dependency injection, connection pooling, async sessions, multiple databases, transaction control6061- **[crud.md](references/crud.md)** - Create, read, update, delete operations, bulk operations, upsert patterns, soft deletes, transaction patterns, FastAPI endpoint integration6263- **[queries.md](references/queries.md)** - Where clauses, ordering, pagination, aggregations, joins, subqueries, dynamic filtering, full-text search, JSON queries, window functions, exists queries6465### Advanced Topics6667- **[migrations.md](references/migrations.md)** - Alembic setup and configuration, creating and applying migrations, migration operations, data migrations, branching and merging, production workflow, FastAPI integration6869- **[testing.md](references/testing.md)** - Test database setup, FastAPI TestClient integration, testing CRUD operations, testing relationships, fixtures, parametrized tests, database isolation, coverage7071- **[performance.md](references/performance.md)** - Connection pooling optimization, query optimization, N+1 problem solutions, indexing strategies, bulk operations, pagination best practices, caching, read replicas, batch processing7273- **[integration.md](references/integration.md)** - FastAPI project structure, application lifespan, router implementation, custom dependencies, response models with relationships, error handling, middleware, background tasks, WebSocket integration7475- **[advanced.md](references/advanced.md)** - Transaction management, nested transactions, cascading deletes, soft deletes, event listeners, optimistic locking, database constraints, custom field types, security best practices, monitoring and logging7677## Common Workflows7879### Creating a New Model80811. Define the model in your models file822. Add relationships if needed833. Create request/response schemas844. Generate migration: `alembic revision --autogenerate -m "Add model"`855. Review and apply migration: `alembic upgrade head`866. Implement CRUD functions877. Create API endpoints888. Write tests8990### Setting Up Database91921. Install dependencies: `pip install sqlmodel psycopg2-binary alembic`932. Create database configuration in `database.py`943. Define models in `models.py`954. Initialize Alembic: `alembic init alembic`965. Configure Alembic for SQLModel (see [migrations.md](references/migrations.md))976. Create initial migration987. Set up dependency injection for sessions99100### Optimizing Performance1011021. Add indexes on frequently queried columns (see [models.md](references/models.md))1032. Use eager loading for relationships (see [relationships.md](references/relationships.md))1043. Configure connection pooling (see [sessions.md](references/sessions.md))1054. Implement pagination (see [queries.md](references/queries.md))1065. Use bulk operations for multiple inserts/updates (see [crud.md](references/crud.md))1076. Add query caching if needed (see [performance.md](references/performance.md))108109### Adding Relationships1101111. Define foreign key in child model1122. Add `Relationship` field in both models1133. Use `back_populates` to link them1144. For many-to-many, create link table1155. Configure cascade behavior if needed (see [relationships.md](references/relationships.md))1166. Update migrations1177. Test relationship loading118119## When to Use Each Reference120121- **Starting a new project?** Read: sessions.md → models.md → integration.md122- **Need relationships?** Read: relationships.md123- **Writing queries?** Read: queries.md124- **Performance issues?** Read: performance.md → queries.md125- **Setting up testing?** Read: testing.md126- **Database migrations?** Read: migrations.md127- **Building CRUD endpoints?** Read: crud.md → integration.md128- **Advanced features?** Read: advanced.md129130## Best Practices Summary131132### Model Design133134- Use `Optional[int]` with `default=None` for auto-increment primary keys135- Add indexes to foreign keys and frequently queried fields136- Use enums for status/category fields137- Separate table models from request/response models138- Use mixins for common fields (created_at, updated_at)139140### Session Management141142- Always use dependency injection in FastAPI endpoints143- Use context managers (`with Session()`) for manual sessions144- Configure connection pooling for production145- Set `pool_pre_ping=True` to handle stale connections146147### Queries148149- Use eager loading to avoid N+1 queries150- Add appropriate indexes before querying large datasets151- Use cursor-based pagination for large result sets152- Use `select()` for all queries instead of legacy query API153154### Migrations155156- Always review auto-generated migrations before applying157- Test migrations locally before production158- Make migrations reversible (implement both upgrade and downgrade)159- Use separate migrations for schema and data changes160161### Testing162163- Use SQLite in-memory database for tests164- Use fixtures for test data165- Override FastAPI dependencies in tests166- Test both success and failure cases167168### Performance169170- Index foreign keys and frequently queried columns171- Use bulk operations for multiple inserts/updates172- Configure appropriate pool sizes based on load173- Monitor slow queries and optimize them174175### Security176177- Never use string formatting for queries (use parameterized queries)178- Hash passwords with bcrypt or similar179- Validate all user input with Pydantic180- Use environment variables for database credentials181- Handle database errors gracefully without exposing internals182183## Example Project Structure184185```text186app/187├── __init__.py188├── main.py # FastAPI app with lifespan189├── database.py # Engine and session setup190├── models.py # SQLModel definitions191├── crud.py # CRUD operations192├── dependencies.py # FastAPI dependencies193├── config.py # Settings with pydantic-settings194├── routers/195│ ├── __init__.py196│ ├── users.py197│ └── posts.py198└── tests/199 ├── __init__.py200 ├── conftest.py # Test fixtures201 ├── test_users.py202 └── test_posts.py203204alembic/205├── versions/206│ └── *.py # Migration files207├── env.py # Alembic configuration208└── script.py.mako209210.env # Environment variables211alembic.ini # Alembic config212pyproject.toml # Dependencies213```214215## Troubleshooting216217### Common Issues218219**Import errors with SQLModel models:**220221- Ensure all models are imported in `alembic/env.py`222- Import models before calling `SQLModel.metadata.create_all()`223224**N+1 query problems:**225226- Use `selectinload()` or `joinedload()` for relationships227- Check query logs with `echo=True` on engine228229**Connection pool exhausted:**230231- Increase `pool_size` and `max_overflow`232- Ensure sessions are properly closed (use context managers)233- Check for long-running transactions234235**Migration conflicts:**236237- Use `alembic heads` to check for multiple heads238- Merge branches with `alembic merge`239- Resolve conflicts manually in migration files240241**Slow queries:**242243- Add indexes on queried columns244- Use `EXPLAIN ANALYZE` to check query plan245- Consider using read replicas for read-heavy workloads246247## Additional Resources248249For 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.