migrate
A thin wrapper around Alembic that replaces long, hard-to-remember commands with short, consistent ones. No Alembic knowledge required — just four sub-commands cover everything.
Overview
Alembic is powerful but verbose. FastKit CLI wraps its most common operations so you don't need to remember the flags:
fastkit migrate make -m "msg"
alembic revision --autogenerate -m "msg"
fastkit migrate run
alembic upgrade head
fastkit migrate rollback
alembic downgrade -1
fastkit migrate status
alembic current
These commands require an existing Alembic configuration in your project (alembic.ini and alembic/env.py). If you don't have one yet, see Alembic Setup at the bottom of this page.
migrate make
Generates a new migration file by comparing your SQLAlchemy models to the current database schema. Always run this after changing a model.
| Option | Short | Required | Description |
|---|---|---|---|
--message |
-m |
Yes | Short description used in the migration filename |
fastkit migrate make -m "create_invoices"
fastkit migrate make -m "add_status_to_invoices"
fastkit migrate make -m "create_users_and_clients"
The generated file is placed in alembic/versions/ with a timestamp prefix and your message as the filename. Review it before running to make sure the autogenerated SQL matches your intent:
# alembic/versions/20260320_112301_create_invoices.py
def upgrade() -> None:
op.create_table(
'invoices',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('client_id', sa.Integer(), nullable=True),
sa.Column('number', sa.String(50), nullable=True),
sa.Column('total', sa.Float(), nullable=True),
sa.Column('status', sa.String(20), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.PrimaryKeyConstraint('id')
)
def downgrade() -> None:
op.drop_table('invoices')
Always review the generated migration before running it. Alembic's autogenerate does not detect every change — renaming a column, for example, may appear as a drop + add instead of a rename.
migrate run
Applies all pending migrations up to head — equivalent to alembic upgrade head.
fastkit migrate run
If there are no pending migrations, the command exits silently with no output. Idempotent — safe to run multiple times.
migrate rollback
Rolls back the most recently applied migration — one step at a time. Equivalent to alembic downgrade -1.
fastkit migrate rollback
To roll back multiple steps, run the command multiple times — one rollback per call. This is intentional: it forces you to be deliberate about each step reverted.
Rollback runs the downgrade() function in your migration file. If that function drops a table or column, the data is gone. In production, always back up the database before rolling back.
migrate status
Shows the current migration revision applied to the database — equivalent to alembic current.
fastkit migrate status
If the output shows (head) your database is fully up to date. Any other output means there are pending migrations — run fastkit migrate run to apply them.
Typical Workflow
The everyday migration cycle when adding or changing a model:
modules/invoices/models.pyfastkit migrate make -m "add_status_to_invoices"
alembic/versions/<timestamp>_add_status_to_invoices.py and confirm the SQL looks correctfastkit migrate run
fastkit migrate status # should show (head)
Rollback scenario
# Something went wrong after running a migration
fastkit migrate rollback # undo last migration
# Fix the migration file, then re-apply
fastkit migrate run
Alembic Setup
If your project doesn't have Alembic configured yet, initialize it first:
alembic init alembic
This creates alembic.ini and the alembic/ directory. Then configure your database URL in alembic/env.py:
# alembic/env.py
from fastkit_core.database import Base
from fastkit_core.config import ConfigManager
# Import all models so Alembic can detect them
from modules.invoices.models import Invoice
from modules.clients.models import Client
# ... add more models here
config = ConfigManager(modules=['database'], auto_load=True)
# Point Alembic at your metadata and database URL
target_metadata = Base.metadata
def get_url():
return config.database.DATABASE_URL
When you run fastkit make module, the model import is automatically added to alembic/env.py. Manual setup is only needed for the initial configuration or for models generated outside of FastKit CLI.