Alembic
Comprehensive Alembic database migration management for customer support systems
- Skill ID
- manutej/luxor-claude-marketplace/alembic
- Publisher
- manutej
- Repository
- luxor-claude-marketplace
- Installs
- 0
- Files
- 4
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
manutej/luxor-claude-marketplace/alembicInstalls these files- EXAMPLES.md
- README.md
- SKILL.md
- VERIFICATION.txt
What this skill tells the agent
Alembic Database Migration Management Skill
Overview
This skill provides comprehensive guidance for managing database migrations using Alembic in customer support environments. It covers everything from initial setup through complex production deployment scenarios, with a focus on maintaining data integrity and minimizing downtime for support operations.
Core Concepts
What is Alembic?
Alembic is a lightweight database migration tool for use with SQLAlchemy. It provides a way to manage changes to your database schema over time through version-controlled migration scripts. For customer support systems, this means:
- Version Control: Track all schema changes in your support database
- Reproducibility: Apply the same migrations across dev, staging, and production
- Rollback Capability: Safely revert problematic changes
- Team Collaboration: Merge schema changes from multiple developers
- Data Preservation: Migrate data during schema transformations
Migration Lifecycle in Support Systems
- Development: Create migrations locally while developing new features
- Testing: Validate migrations in staging environment
- Review: Code review migration scripts before production
- Deployment: Apply migrations to production with minimal downtime
- Monitoring: Track migration status and handle failures
- Rollback: Revert if issues arise in production
Installation and Initial Setup
Installing Alembic
# Install Alembic with PostgreSQL support
pip install alembic psycopg2-binary sqlalchemy
# Or add to requirements.txt
alembic>=1.13.0
sqlalchemy>=2.0.0
psycopg2-binary>=2.9.0Initialize Alembic in Your Project
# Initialize Alembic (creates alembic/ directory and alembic.ini)
alembic init alembic
# For multiple database support
alembic init --template multidb alembicThis creates:
alembic/: Directory containing migration scriptsalembic/versions/: Where individual migration files livealembic/env.py: Migration environment configurationalembic.ini: Alembic configuration file
Configure Database Connection
Edit alembic.ini to set your database URL:
# For development
sqlalchemy.url = postgresql://user:password@localhost/support_dev
# For production (use environment variables)
sqlalchemy.url = postgresql://%(DB_USER)s:%(DB_PASSWORD)s@%(DB_HOST)s/%(DB_NAME)sBetter approach - use environment variables in env.py:
import os
from logging.config import fileConfig
from sqlalchemy import engine_from_config, pool
from alembic import context
# Import your models
from myapp.models import Base
# This is the Alembic Config object
config = context.config
# Override sqlalchemy.url from environment
db_url = os.getenv('DATABASE_URL', 'postgresql://localhost/support_dev')
config.set_main_option('sqlalchemy.url', db_url)
# Set up target metadata for autogenerate
target_metadata = Base.metadataCreating Migrations
Manual Migration Creation
Create a migration manually when you need precise control:
# Create empty migration file
alembic revision -m "add ticket priority column"This generates a file like versions/abc123_add_ticket_priority_column.py:
"""add ticket priority column
Revision ID: abc123
Revises: def456
Create Date: 2025-01-15 10:30:00.000000
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers
revision = 'abc123'
down_revision = 'def456'
branch_labels = None
depends_on = None
def upgrade() -> None:
# Add priority column to tickets table
op.add_column('tickets',
sa.Column('priority', sa.String(20), nullable=True, server_default='normal')
)
# Create index for performance
op.create_index('ix_tickets_priority', 'tickets', ['priority'])
def downgrade() -> None:
# Remove index first
op.drop_index('ix_tickets_priority', 'tickets')
# Remove column
op.drop_column('tickets', 'priority')Autogenerate Migrations
Let Alembic detect schema changes automatically:
# Generate migration by comparing models to database
alembic revision --autogenerate -m "add customer satisfaction table"Important: Always review autogenerated migrations! They may miss:
- Renamed columns (appears as drop + add)
- Changed column types requiring data conversion
- Complex constraints
- Data migrations
Example autogenerated migration:
"""add customer satisfaction table
Revision ID: xyz789
Revises: abc123
Create Date: 2025-01-15 11:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
revision = 'xyz789'
down_revision = 'abc123'
branch_labels = None
depends_on = None
def upgrade() -> None:
# Auto-generated - review before running!
op.create_table(
'customer_satisfaction',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('ticket_id', sa.Integer(), nullable=False),
sa.Column('rating', sa.Integer(), nullable=False),
sa.Column('feedback', sa.Text(), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(['ticket_id'], ['tickets.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id')
)
op.create_index('ix_satisfaction_ticket_id', 'customer_satisfaction', ['ticket_id'])
op.create_index('ix_satisfaction_created_at', 'customer_satisfaction', ['created_at'])
def downgrade() -> None:
op.drop_index('ix_satisfaction_created_at', 'customer_satisfaction')
op.drop_index('ix_satisfaction_ticket_id', 'customer_satisfaction')
op.drop_table('customer_satisfaction')Data Migrations
Migrating Data During Schema Changes
When you need to transform existing data:
"""convert ticket status to new enum
Revision ID: data001
Revises: xyz789
Create Date: 2025-01-15 12:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.sql import table, column
revision = 'data001'
down_revision = 'xyz789'
def upgrade() -> None:
# Create new status column
op.add_column('tickets',
sa.Column('status_new', sa.String(50), nullable=True)
)
# Migrate data using bulk update
tickets = table('tickets',
column('status', sa.String),
column('status_new', sa.String)
)
# Map old statuses to new ones
status_mapping = {
'open': 'OPEN',
'in_progress': 'IN_PROGRESS',
'pending': 'WAITING_ON_CUSTOMER',
'resolved': 'RESOLVED',
'closed': 'CLOSED'
}
connection = op.get_bind()
for old_status, new_status in status_mapping.items():
connection.execute(
tickets.update().where(
tickets.c.status == old_status
).values(status_new=new_status)
)
# Make new column non-nullable now that data is migrated
op.alter_column('tickets', 'status_new', nullable=False)
# Drop old column and rename new one
op.drop_column('tickets', 'status')
op.alter_column('tickets', 'status_new', new_column_name='status')
def downgrade() -> None:
# Reverse the migration
op.add_column('tickets',
sa.Column('status_old', sa.String(50), nullable=True)
)
tickets = table('tickets',
column('status', sa.String),
column('status_old', sa.String)
)
# Reverse mapping
reverse_mapping = {
'OPEN': 'open',
'IN_PROGRESS': 'in_progress',
'WAITING_ON_CUSTOMER': 'pending',
'RESOLVED': 'resolved',
'CLOSED': 'closed'
}
connection = op.get_bind()
for new_status, old_status in reverse_mapping.items():
connection.execute(
tickets.update().where(
tickets.c.status == new_status
).values(status_old=old_status)
)
op.alter_column('tickets', 'status_old', nullable=False)
op.drop_column('tickets', 'status')
op.alter_column('tickets', 'status_old', new_column_name='status')More from manutej
Use this skill in a project
Open any RiverX project, search the Skills panel for manutej/luxor-claude-marketplace/alembic, and install it in one click.
