Use this skill when the user wants to run database migrations, manage schema changes, use alembic, upgrade or downgrade a database schema, or track schema versions.
72
88%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Manages database schema migrations safely: Alembic for SQLAlchemy projects, raw SQL with version tracking for others. Always backup before migrating, always support rollback.
pip install alembic sqlalchemy
alembic init migrations
# Edit migrations/env.py to set your DATABASE_URL and metadataalembic revision --autogenerate -m "add users table"alembic upgrade head # apply all pending
alembic upgrade +1 # apply next one
alembic downgrade -1 # roll back one
alembic downgrade base # roll back everythingfrom alembic.config import Config
from alembic import command
def migrate(db_url: str, direction: str = "head") -> None:
cfg = Config("alembic.ini")
cfg.set_main_option("sqlalchemy.url", db_url)
if direction == "head":
command.upgrade(cfg, "head")
elif direction.startswith("-") or direction.startswith("+"):
command.upgrade(cfg, direction)
else:
command.downgrade(cfg, direction)def get_migration_status(db_url: str) -> dict:
from alembic.runtime.migration import MigrationContext
from sqlalchemy import create_engine
engine = create_engine(db_url)
with engine.connect() as conn:
ctx = MigrationContext.configure(conn)
return {
"current": ctx.get_current_revision(),
"heads": ctx.get_current_heads(),
}import sqlite3 # or psycopg2 / pymysql
def ensure_migrations_table(conn) -> None:
conn.execute("""
CREATE TABLE IF NOT EXISTS schema_migrations (
version TEXT PRIMARY KEY,
applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
def get_applied(conn) -> set[str]:
return {row[0] for row in conn.execute("SELECT version FROM schema_migrations")}
def apply_migration(conn, version: str, sql: str) -> None:
applied = get_applied(conn)
if version in applied:
return
conn.executescript(sql) if hasattr(conn, "executescript") else conn.execute(sql)
conn.execute("INSERT INTO schema_migrations (version) VALUES (?)", (version,))
conn.commit()
print(f"Applied migration {version}")
# Usage:
MIGRATIONS = {
"001_create_users": """
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
""",
"002_add_name": "ALTER TABLE users ADD COLUMN name TEXT;",
}
def run_all(conn) -> None:
ensure_migrations_table(conn)
for version, sql in sorted(MIGRATIONS.items()):
apply_migration(conn, version, sql)import psycopg2
def pg_migrate(dsn: str, migration_sql: str) -> None:
"""Run a migration in a transaction — rolls back on error."""
conn = psycopg2.connect(dsn)
try:
with conn:
with conn.cursor() as cur:
cur.execute(migration_sql)
print("Migration applied.")
except Exception as e:
print(f"Migration FAILED, rolled back: {e}")
raise
finally:
conn.close()import subprocess, datetime
def backup_postgres(dsn: str, output_dir: str = ".") -> str:
stamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
out = f"{output_dir}/backup_{stamp}.sql"
subprocess.run(["pg_dump", dsn, "-f", out], check=True)
return out
def backup_sqlite(db_path: str, output_dir: str = ".") -> str:
import shutil, datetime
stamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
out = f"{output_dir}/backup_{stamp}.db"
shutil.copy2(db_path, out)
return out| Task | Tool | Command |
|---|---|---|
| Auto-gen migration | alembic | alembic revision --autogenerate -m "..." |
| Apply all | alembic | alembic upgrade head |
| Rollback one | alembic | alembic downgrade -1 |
| Show history | alembic | alembic history --verbose |
| Current version | alembic | alembic current |
| Backup PostgreSQL | pg_dump | pg_dump $DSN -f backup.sql |
| Backup SQLite | shutil.copy2 | Copy the .db file |
32f0050
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.