When you're first setting up your environment, ensure that migrations are run
against your db so it has all the required tables. make init
does this, but if
needing to work with the migrations directly, some common commands:
make db-upgrade # Apply pending migrations to db
make db-downgrade # Rollback last migration to db
make db-downgrade-all # Rollback all migrations
If you've changed a python object model, auto-generate a migration file for the database and run it:
$ make db-migrate-create MIGRATE_MSG="<brief description of change>"
$ make db-upgrade
Example: Adding a new column to an existing table:
- Manually update the database models with the changes (eligibility-models.py in this example)
class ExampleTable(Base):
...
my_new_timestamp = Column(TIMESTAMP(timezone=True)) # Newly added line
- Automatically generate a migration file with
make db-migrate-create MIGRATE_MSG="Add created_at timestamp to address table"
...
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column("example_table", sa.Column("my_new_timestamp", sa.TIMESTAMP(timezone=True), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("example_table", "my_new_timestamp")
# ### end Alembic commands ###
- Manually adjust the migration file as needed. Some changes will not fully auto-generate (like foreign keys), so make sure that all desired changes are included.
Alembic migrations form an ordered history, with each migration having at least
one parent migration as specified by the down_revision
variable. This can be
visualized by:
make db-migrate-history
When multiple migrations are created that point to the same down_revision
a
branch is created, with the tip of each branch being a "head". The above history
command will show this, but a list of just the heads can been retrieved with:
make db-migrate-heads
CI/CD runs migrations to reach the "head". When there are multiple, Alembic
can't resolve which migrations need to be run. If you run into this error,
you'll need to fix the migration branches/heads before merging to main
.
If the migrations don't depend on each other, which is likely if they've branched, then you can just run:
make db-migrate-merge-heads
Which will create a new migration pointing to all current "head"s, effectively pulling them all together.
Or, if you wish to avoid creating extra migrations, you can manually adjust
the down_revision
of one of the migrations to point to the other one. This
is also the necessary approach if the migrations need to happen in a defined
order.