Alembic Convergerο
Safely converge Alembic migration graphs by automatically generating minimal merge migrations.
Alembic Converger is a production-grade Python tool that detects and resolves multiple migration heads in your Alembic migration history. It creates graph-only merge migrations without modifying schema operations, ensuring safe convergence for teams working with parallel database migrations.
The Problemο
When multiple developers work on database migrations in parallel, or when merging feature branches, you often end up with multiple heads in your Alembic migration graph:
[feature-1] [feature-2]
| |
rev-abc rev-def
\ /
\ /
[main branch]
|
rev-123
Alembic requires a single linear path to head, and having multiple heads can cause:
Failed deployments
CI/CD pipeline failures
Confusion about which migrations to apply
Why Alembic Converger?ο
Traditional approach:
# Manual merge - error-prone and time-consuming
alembic merge -m "merge heads" rev-abc rev-def
# Did it create schema conflicts? Who knows! π°
With Alembic Converger:
# Automatic, safe convergence
alembic-converger converge --from-revision rev-123
# β Validates merge is graph-only
# β Tests upgrade path automatically
# β Fails fast on conflicts
Safety Guaranteesο
π This tool is designed to be safe by default:
Never modifies existing migrations - Only creates new merge migrations
Never guesses developer intent - Only performs graph-only merges
Never auto-resolves schema conflicts - Fails if merge contains operations
Validates upgrade path - Runs
alembic upgradeafter each mergeDeterministic behavior - Same input always produces same result
Automatic rollback - Deletes created merges on failure
Installationο
pip install alembic-converger
Requirements:
Python 3.8+
Alembic 1.7.0+
Quick Startο
Basic Usageο
# Converge all heads from a base revision
alembic-converger converge --from-revision ae1027a6acf
# Dry run to preview changes
alembic-converger converge --from-revision ae1027a6acf --dry-run
# Skip database validation (faster, less safe)
alembic-converger converge --from-revision ae1027a6acf --skip-validation
# Verbose output for debugging
alembic-converger converge --from-revision ae1027a6acf --verbose
Python APIο
from alembic_converger import converge_migrations
# Programmatic convergence
result = converge_migrations(
base_revision="ae1027a6acf",
config_path="alembic.ini",
dry_run=False,
skip_validation=False,
verbose=True
)
print(f"Created {len(result.merges_created)} merge(s)")
print(f"Final head: {result.final_head}")
How It Worksο
Alembic Converger treats your migrations as a directed acyclic graph (DAG):
Discovery: Find all heads descending from a known base revision
Validation: Ensure all heads share a common ancestor
Convergence: Iteratively merge heads pairwise until one remains
Verification: After each merge:
Validate the merge contains no schema operations
Run
alembic upgradeto test the pathReload the graph and continue
Example Scenarioο
Initial state (3 heads):
head-1 head-2 head-3
\ | /
\ | /
base (ae1027a6acf)
After convergence:
final-head
|
merge-2
/ \
merge-1 head-3
/ \
head-1 head-2
\ | /
base
CI/CD Integrationο
GitHub Actionsο
name: Check Alembic Convergence
on: [pull_request]
jobs:
check-migrations:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install alembic-converger
pip install -r requirements.txt
- name: Check for multiple heads
run: |
# Get the base revision (e.g., from main branch)
BASE_REV=$(git merge-base origin/main HEAD)
# Try to converge (will fail if conflicts exist)
alembic-converger converge \
--from-revision $BASE_REV \
--dry-run
Pre-deployment Hookο
#!/bin/bash
# deploy.sh
echo "Checking for multiple Alembic heads..."
alembic-converger converge --from-revision $(git describe --tags --abbrev=0) --dry-run
if [ $? -eq 0 ]; then
echo "β Migrations converged"
# Continue with deployment
else
echo "β Migration convergence failed"
exit 1
fi
CLI Referenceο
converge Commandο
alembic-converger converge [OPTIONS]
Options:
--from-revision TEXT Base revision to converge from [required]
--alembic-config TEXT Path to alembic.ini [default: alembic.ini]
--dry-run Show what would be done without changes
--skip-validation Skip upgrade validation (not recommended)
--verbose, -v Enable debug logging
--help Show this message and exit
Exit Codesο
0: Success (already converged or successfully merged)1: Convergence failed (validation error, conflicts, etc.)2: Configuration error (invalid alembic.ini, missing files, etc.)
FAQο
Why not just use alembic merge?ο
alembic merge creates a single merge migration but:
Doesnβt validate the merge is conflict-free
Doesnβt test the upgrade path
Requires manual intervention for each merge
Can silently create broken migrations
Alembic Converger automates this safely with validation.
Why not auto-resolve schema conflicts?ο
Safety first. Schema conflicts require developer judgment:
Which column definition to keep?
How to handle conflicting constraints?
What about data migrations?
Auto-resolving could cause data loss or corruption. Instead, we fail fast and let you resolve manually.
When should I use this tool?ο
Perfect for:
β CI/CD pipelines (pre-deployment checks)
β Multi-developer teams with parallel migrations
β Feature branch merges
β Automated migration management
Not suitable for:
β Resolving schema conflicts (requires manual intervention)
β Rewriting migration history (never modifies existing files)
What if validation fails?ο
When validation fails, Alembic Converger:
Logs the detailed error
Rolls back created merge migrations
Exits with code 1
Youβll need to manually resolve conflicts:
# Review the conflicting migrations
alembic history --verbose
# Manually create merge with conflict resolution
alembic merge -m "resolve conflicts" rev-1 rev-2
# Edit the generated file to resolve conflicts
Can I use this without a database?ο
Yes, with --skip-validation:
alembic-converger converge --from-revision X --skip-validation
However, this skips upgrade testing, reducing safety guarantees. Use only when:
Database is not available (e.g., CI without DB)
Youβll test manually later
Architectureο
Alembic Converger is built with clean separation of concerns:
alembic_converger/
βββ cli.py # Click-based CLI interface
βββ config.py # Alembic configuration loading
βββ graph.py # DAG analysis & traversal
βββ merge.py # Merge creation & validation
βββ validate.py # Upgrade path testing
βββ converge.py # Main orchestration algorithm
βββ errors.py # Exception hierarchy
βββ utils.py # Shared utilities
Key Design Principlesο
Graph-first thinking: Migrations are nodes in a DAG, not files
Fail fast: Detect problems early with clear errors
Idempotent: Same input β same output every time
No side effects: Only creates merge files, never modifies existing ones
Observable: Comprehensive logging at every step
Developmentο
Setupο
# Clone the repository
git clone https://github.com/rishav00a/alembic_converger.git
cd alembic_converger
# Create virtual environment
python -m venv venv
source venv/bin/activate # or `venv\Scripts\activate` on Windows
# Install in development mode
pip install -e ".[dev]"
Running Testsο
# Run all tests
pytest
# With coverage
pytest --cov=alembic_converger --cov-report=html
# Run specific test file
pytest tests/test_graph.py -v
Code Qualityο
# Format code
black alembic_converger tests
# Lint code
ruff check alembic_converger tests
# Type checking (optional)
mypy alembic_converger
Publishing to PyPIο
# Install build tools
pip install build twine
# Build distribution
python -m build
# Check package
twine check dist/*
# Upload to TestPyPI (optional)
twine upload --repository testpypi dist/*
# Upload to PyPI
twine upload dist/*
Contributingο
Contributions are welcome! Please:
Fork the repository
Create a feature branch (
git checkout -b feature/amazing-feature)Make your changes with tests
Run tests and linting
Commit your changes (
git commit -m 'Add amazing feature')Push to the branch (
git push origin feature/amazing-feature)Open a Pull Request
Licenseο
This project is licensed under the MIT License - see the LICENSE file for details.
Creditsο
Built with β€οΈ by the open-source community.
Powered by:
Supportο
π Documentation
π Issue Tracker
π¬ Discussions
Remember: This tool is a graph normalizer, not a migration author. It safely converges parallel development paths without guessing your intent. β¨