Alembic Database Migration Workflow
This guide provides a reference for using Alembic to manage your database schema. Alembic allows you to make changes to your database structure in a systematic and version-controlled way.
Core Concepts
- What is Alembic? Alembic is a database migration tool for Python. It allows you to modify your database schema (e.g., add a new table or column) and keep a versioned history of those changes.
- Why use it? It prevents you from having to manually write SQL
ALTER TABLEstatements. It automatically compares your SQLModel classes to the current state of the database and generates the necessary migration scripts.
Standard Schema Change Workflow
This is the recommended process for making schema changes during development.
Step 1: Modify SQLModel Classes
Edit the model files in
src/ca_biositing/datamodels/ca_biositing/datamodels/models/. Models are
organized into domain subdirectories (e.g., field_sampling/, places/,
external_data/).
If adding a new model, also add its import to models/__init__.py so it is
registered with SQLModel.metadata.
Step 2: Auto-Generate a Migration
pixi run migrate-autogenerate -m "Description of your changes"
This compares your SQLModel class definitions against the current database state
and generates a migration script in alembic/versions/.
Step 3: Review the Migration
Always review the generated migration script to ensure it accurately reflects your intended changes. Alembic autogenerate is not perfect and may miss some operations (such as changes to column types or server defaults).
Step 4: Apply the Migration
pixi run migrate
This applies alembic upgrade head against the Docker-hosted database.
Materialized Views
Materialized views are defined in
src/ca_biositing/datamodels/ca_biositing/datamodels/views.py and are not
auto-generated by Alembic. They must be managed through manual migration
scripts.
Creating or modifying a view: Write a manual Alembic revision that uses
CREATE MATERIALIZED VIEW / DROP MATERIALIZED VIEW in the upgrade() and
downgrade() functions.
Refreshing views after data loads:
pixi run refresh-views
Checking view status:
pixi run schema-analytics-list
Manual Migration Workflow
If you need to perform manual Alembic operations (e.g., manual revisions or downgrades), follow these steps.
Important: Run Alembic commands locally using pixi run to ensure the
correct environment and to avoid performance issues with Docker on macOS.
Create a manual revision (empty migration):
DATABASE_URL=postgresql://biocirv_user:biocirv_dev_password@localhost:5432/biocirv_db pixi run alembic revision -m "Your message"
Apply the migration:
pixi run migrate
Collaborative Workflows and Resetting the Database
When working in a team, you may pull new migration files. The standard workflow
is to run pixi run migrate after pulling the latest code.
If you encounter a "multiple heads" conflict or your database gets into an inconsistent state, you can reset the environment.
Resetting the Environment:
- Stop and wipe volumes:
pixi run teardown-services-volumes - Start services:
pixi run start-services - Apply all migrations:
pixi run migrate
How to Downgrade a Migration (Optional)
If you need to undo a migration:
# Downgrade by one version
DATABASE_URL=postgresql://biocirv_user:biocirv_dev_password@localhost:5432/biocirv_db pixi run alembic downgrade -1