Loading...
Loading...
This skill should be used when the user asks to "set up Alembic migrations", "create a database migration", "run alembic upgrade", "configure alembic autogenerate", or needs guidance on SQLAlchemy schema versioning and migration best practices.
npx skill4agent add the-perfect-developer/the-perfect-opencode alembicdown_revision# Generic single-database (most common)
alembic init alembic
# pyproject.toml-integrated (modern projects)
alembic init --template pyproject alembic
# Async DBAPI support
alembic init --template async alembicpyprojectpyproject.tomlpyproject.tomlalembic.iniyourproject/
├── alembic.ini # DB URL, logging, deployment config
├── pyproject.toml # Source/code config (pyproject template)
└── alembic/
├── env.py # Migration runner — customize here
├── script.py.mako # Template for new revision files
└── versions/
├── 3512b954651e_add_account.py
└── ae1027a6acf_add_column.pyalembic.inisqlalchemy.url = postgresql+psycopg2://user:pass@localhost/mydb%import urllib.parse
from sqlalchemy import URL
url = URL.create("postgresql+psycopg2", username="scott", password="P@ss%rd", host="localhost")
# Renders as: postgresql+psycopg2://scott:P%40ss%25rd@localhost
# In alembic.ini: postgresql+psycopg2://scott:P%%40ss%%25rd@localhostenv.py# env.py
import os
config.set_main_option("sqlalchemy.url", os.environ["DATABASE_URL"])env.pyMetaData# env.py — replace the None assignment
from myapp.models import Base
target_metadata = Base.metadataMetaDatafrom sqlalchemy import MetaData
from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
metadata = MetaData(naming_convention={
"ix": "ix_%(column_0_label)s",
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_`%(constraint_name)s`",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s",
})unique=Trueindex=True# Manual (empty script)
alembic revision -m "add account table"
# Autogenerate from model diff
alembic revision --autogenerate -m "add account table""""add account table
Revision ID: 1975ea83b712
Revises: <previous_rev_id or None>
Create Date: 2024-01-15 10:30:00
"""
revision = '1975ea83b712'
down_revision = None # None = first migration
branch_labels = None
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table(
'account',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('name', sa.String(50), nullable=False),
sa.Column('created_at', sa.DateTime, nullable=False),
)
def downgrade():
op.drop_table('account')downgrade()alembic downgrade# Add a column
op.add_column('account', sa.Column('email', sa.String(255)))
# Drop a column
op.drop_column('account', 'email')
# Add named foreign key (naming convention resolves the name)
op.create_foreign_key(
None, 'order', 'account',
['account_id'], ['id']
)
# Drop constraint — use op.f() to bypass naming convention tokenization
op.drop_constraint(op.f('fk_order_account_id_account'), 'order', type_='foreignkey')
# Create index
op.create_index('ix_account_name', 'account', ['name'])# Upgrade to latest
alembic upgrade head
# Upgrade to specific revision (partial ID works)
alembic upgrade ae10
# Upgrade N steps forward
alembic upgrade +2
# Downgrade to base (undo all)
alembic downgrade base
# Downgrade N steps backward
alembic downgrade -1# Show current DB revision
alembic current
# Show full history
alembic history --verbose
# Show history range
alembic history -r1975ea:ae1027
# Check if new migrations needed (CI-friendly)
alembic checkalembic checkalembic.ini[post_write_hooks]
hooks = ruff
ruff.type = exec
ruff.executable = ruff
ruff.options = check --fix REVISION_SCRIPT_FILENAMEpyproject.toml[[tool.alembic.post_write_hooks]]
name = "ruff"
type = "exec"
executable = "ruff"
options = "check --fix REVISION_SCRIPT_FILENAME"| Command | Description |
|---|---|
| Initialize migration environment |
| Create empty revision |
| Generate revision from model diff |
| Apply all pending migrations |
| Roll back all migrations |
| Show current DB revision |
| List all revisions |
| Assert no pending migrations (CI) |
MetaDatadowngrade()alembic checkpyprojectop.f()references/env-configuration.mdenv.pyinclude_nameinclude_objectreferences/autogenerate-guide.mdalembic check