Alembic migration patterns with automatic handling of problematic types.
From fastapinpx claudepluginhub ruslan-korneev/claude-plugins --plugin fastapiThis skill uses the workspace's default tool permissions.
references/enum-handling.mdGuides Payload CMS config (payload.config.ts), collections, fields, hooks, access control, APIs. Debugs validation errors, security, relationships, queries, transactions, hook behavior.
Designs scalable batch/streaming data pipelines, warehouses, lakehouses using Spark, dbt, Airflow, Kafka/Flink, and cloud platforms like Snowflake, BigQuery, Databricks.
Builds production Apache Airflow DAGs using best practices for operators, sensors, testing, and deployment. For data pipelines, workflow orchestration, and batch jobs.
Alembic migration patterns with automatic handling of problematic types.
Use this skill when the user:
Alembic does not always correctly generate downgrade. The plugin automatically:
More details: ${CLAUDE_PLUGIN_ROOT}/skills/alembic-patterns/references/enum-handling.md
status_type = sa.Enum("pending", "active", "inactive", name="status_type")
def upgrade() -> None:
op.create_table(
"orders",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("status", status_type, nullable=False),
sa.PrimaryKeyConstraint("id"),
)
def downgrade() -> None:
op.drop_table("orders")
status_type.drop(op.get_bind(), checkfirst=False) # IMPORTANT!
def upgrade() -> None:
status_type = sa.Enum("pending", "active", name="status_type")
status_type.create(op.get_bind(), checkfirst=True)
op.add_column("orders", sa.Column("status", status_type))
def downgrade() -> None:
op.drop_column("orders", "status")
# Delete only if enum is not used elsewhere
# sa.Enum(name="status_type").drop(op.get_bind(), checkfirst=True)
# Changing NULL -> NOT NULL
def upgrade() -> None:
# First update data
op.execute("UPDATE users SET name = 'Unknown' WHERE name IS NULL")
# Then change constraint
op.alter_column("users", "name", nullable=False)
def downgrade() -> None:
op.alter_column("users", "name", nullable=True)
# Correct order in downgrade
def downgrade() -> None:
# First delete FK
op.drop_constraint("fk_orders_user_id", "orders", type_="foreignkey")
# Then table
op.drop_table("users")
# Changing array element type
def upgrade() -> None:
op.drop_column("users", "tags")
op.add_column("users", sa.Column("tags", sa.ARRAY(sa.String(100))))
def downgrade() -> None:
op.drop_column("users", "tags")
op.add_column("users", sa.Column("tags", sa.ARRAY(sa.String(50))))
def upgrade() -> None:
# Safe batch update for large tables
connection = op.get_bind()
connection.execute(
sa.text("""
UPDATE users
SET status = 'active'
WHERE status IS NULL
""")
)
# Create migration
alembic revision --autogenerate -m "description"
# Apply
alembic upgrade head
# Rollback
alembic downgrade -1
# Check current version
alembic current
# History
alembic history
/migrate:create <message> — create migration with auto-fix/migrate:check [revision] — check migration for problemsmigration-reviewer — full migration analysis