Docs / fastkit-cli / migrate

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 command Alembic equivalent
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.

fastkit migrate make -m <message>
OptionShortRequiredDescription
--message -m Yes Short description used in the migration filename
bash
fastkit migrate make -m "create_invoices"
fastkit migrate make -m "add_status_to_invoices"
fastkit migrate make -m "create_users_and_clients"
Terminal
$ fastkit migrate make -m "create_invoices"
Generating revision...
✓  alembic/versions/20260320_112301_create_invoices.py

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:

python
# 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
bash
fastkit migrate run
Terminal
$ fastkit migrate run
Running upgrade head...
✓  20260318_create_users — done
✓  20260319_create_clients — done
✓  20260320_create_invoices — done

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
bash
fastkit migrate rollback
Terminal
$ fastkit migrate rollback
Running downgrade -1...
✓  20260320_create_invoices — reverted

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
bash
fastkit migrate status
Terminal — up to date
$ fastkit migrate status
20260320_create_invoices (head)
Terminal — pending migrations exist
$ fastkit migrate status
20260319_create_clients
(not at head — run: fastkit migrate run)

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:

1
Edit your model
Add or change fields in modules/invoices/models.py
2
Generate the migration
bash
fastkit migrate make -m "add_status_to_invoices"
3
Review the generated file
Open alembic/versions/<timestamp>_add_status_to_invoices.py and confirm the SQL looks correct
4
Apply the migration
bash
fastkit migrate run
5
Verify
bash
fastkit migrate status   # should show (head)

Rollback scenario

bash
# 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:

bash
alembic init alembic

This creates alembic.ini and the alembic/ directory. Then configure your database URL in alembic/env.py:

python
# 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.