This project demonstrates how to set up a FastAPI application using SQLModel with a PostgreSQL database and handle database migrations using Alembic in a separate Docker container.
api/
├── __init__.py
├── models.py
├── migration_service/
│ ├── Dockerfile
│ ├── alembic.ini
│ ├── env.py
│ ├── requirements.txt
│ ├── entrypoint.sh
│ └── versions/
└── docker-compose.yml
- Docker
- Docker Compose
Build and start the services defined in the docker-compose.yml
file:
docker-compose up --build
Ensure you have the necessary dependencies listed in the requirements.txt
for both the FastAPI app and the migration service.
alembic
psycopg2
sqlmodel
Update the alembic.ini
file with your database connection string:
sqlalchemy.url = postgresql+psycopg2://username:password@db/mydatabase
Ensure your models are imported correctly in env.py
:
from logging.config import fileConfig
from sqlalchemy import engine_from_config, pool
from sqlmodel import SQLModel
from alembic import context
config = context.config
fileConfig(config.config_file_name)
from app.models import MyModel1, MyModel2 # Import your models here
target_metadata = SQLModel.metadata
def run_migrations_offline():
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
)
with context.begin_transaction():
context.run_migrations()
def run_migrations_online():
connectable = engine_from_config(
config.get_section(config.config_ini_section),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata,
)
with context.begin_transaction():
context.run_migrations()
if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()
Create an entrypoint script to handle the migration process:
#!/bin/bash
# Wait for the database to be available
while ! nc -z db 5432; do
echo "Waiting for database..."
sleep 1
done
# Run Alembic migrations
alembic upgrade head
echo "Database migration completed."
Whenever you make changes to your models, follow these steps:
-
Generate a new migration script:
docker-compose run migration alembic revision --autogenerate -m "Describe your changes"
-
Apply the migration:
docker-compose run migration alembic upgrade head
The FastAPI application will be accessible at http://localhost:8000
.
from fastapi import FastAPI
from sqlmodel import SQLModel, Field
app = FastAPI()
class MyModel1(SQLModel, table=True):
id: int = Field(default=None, primary_key=True)
name: str
@app.get("/")
def read_root():
return {"message": "Hello, World!"}
This project is licensed under the MIT License.