Alembic
raw JSON → 1.18.4 verified Tue May 12 auth: no python install: verified quickstart: verified
Database migration tool for SQLAlchemy. Manages schema versioning via migration scripts. Current version: 1.18.4 (Mar 2026). Tightly coupled to SQLAlchemy — version mismatch causes silent failures. SQLAlchemy 1.3 dropped in Alembic 1.15. Python 3.8 dropped in Alembic 1.15. The #1 footgun: autogenerate generates empty migrations when target_metadata is not correctly set in env.py.
pip install alembic Common errors
error ModuleNotFoundError: No module named 'alembic' ↓
cause Alembic is not installed in the Python environment.
fix
pip install alembic
error ModuleNotFoundError: No module named 'infra' ↓
cause The 'infra' module is not found due to incorrect import paths in env.py.
fix
Ensure the correct import path in env.py, e.g., 'from src.infra.sqlalchemy.config.database import Base'.
error ModuleNotFoundError: No module named 'backend' ↓
cause Alembic cannot locate the 'backend' module due to missing sys.path configuration.
fix
Add 'sys.path.append(os.path.abspath(os.path.dirname(__file__)))' in env.py to include the project directory in sys.path.
error AttributeError: 'NoneType' object has no attribute 'execute' ↓
cause This error occurs when a database connection is not properly established, leading to a NoneType object where a database engine is expected.
fix
Ensure that the database engine is correctly configured and connected in env.py.
error No changes detected (alembic revision --autogenerate produces empty migration file) ↓
cause Alembic's autogenerate feature produces an empty migration because target_metadata is not correctly set in env.py, preventing it from seeing your SQLAlchemy models, or because Base.metadata.create_all() was used in your application, creating tables directly and thus making Alembic believe no migrations are needed.
fix
Ensure all SQLAlchemy model files are imported into alembic/env.py and that
target_metadata is correctly assigned to your application's MetaData object (e.g., target_metadata = Base.metadata). Avoid using Base.metadata.create_all() for schema creation in environments managed by Alembic. Warnings
breaking target_metadata = None in env.py causes autogenerate to produce completely empty migration files. This is the default after 'alembic init'. Must be changed to Base.metadata. ↓
fix In env.py: import your models then set target_metadata = Base.metadata
breaking 'Target database is not up to date' error when running --autogenerate. DB must be at head before generating new migrations. ↓
fix Run 'alembic upgrade head' first, then run --autogenerate.
breaking SQLAlchemy 1.3 support dropped in Alembic 1.15. Python 3.8 support dropped in Alembic 1.15. ↓
fix Use SQLAlchemy >= 1.4 and Python >= 3.9 with Alembic 1.15+
gotcha Autogenerate cannot detect everything. It misses: stored procedures, views, partial indexes (pre-1.12), CHECK constraints, column defaults (in some cases). Always manually review generated migrations. ↓
fix Always run 'alembic check' and manually review generated migration files before applying.
gotcha Multiple heads error: 'Multiple head revisions are present' when two migrations both point to the same parent. Happens when multiple developers generate migrations from the same base. ↓
fix Run 'alembic merge heads -m merge' to create a merge migration. Then 'alembic upgrade head'.
gotcha Autogenerate generates 'create table' for all tables instead of 'add column' when models are not imported before autogenerate runs. Models must be imported in env.py so SQLAlchemy metadata is populated. ↓
fix Import all model files in env.py before target_metadata = Base.metadata.
gotcha alembic.ini sqlalchemy.url hardcodes the database URL. For production, override it in env.py using environment variables. ↓
fix In env.py: config.set_main_option('sqlalchemy.url', os.environ['DATABASE_URL'])
gotcha Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead. ↓
fix Always use a virtual environment (e.g., `python -m venv .venv`) to install Python packages to avoid permission issues and system package manager conflicts. Avoid running pip commands with `sudo` unless absolutely necessary for system-wide tools, which is generally not recommended for application dependencies.
gotcha Running pip as root can lead to broken permissions and conflicts with the system package manager, potentially rendering the system unusable. ↓
fix It is recommended to use a virtual environment or run pip as a non-root user. If running as root is intentional, use the `--root-user-action` option to suppress this warning.
Install compatibility verified last tested: 2026-05-12
python os / libc status wheel install import disk
3.10 alpine (musl) - - - 45.6M
3.10 slim (glibc) - - - 44M
3.11 alpine (musl) - - - 51.2M
3.11 slim (glibc) - - - 50M
3.12 alpine (musl) - - - 42.4M
3.12 slim (glibc) - - - 41M
3.13 alpine (musl) - - - 41.8M
3.13 slim (glibc) - - - 40M
3.9 alpine (musl) - - - 44.2M
3.9 slim (glibc) - - - 43M
Imports
- env.py target_metadata wrong
# In alembic/env.py target_metadata = None # default — autogenerate generates EMPTY migrationscorrect# In alembic/env.py — MUST import your models for autogenerate to work from myapp.models import Base # import all models so metadata is populated target_metadata = Base.metadata # If models are in multiple files, import them all: from myapp.models.user import User from myapp.models.post import Post # then: target_metadata = Base.metadata - alembic init + upgrade wrong
# Wrong: running autogenerate before DB is up to date alembic revision --autogenerate -m 'add column' # fails if DB not at headcorrect# CLI commands — run from project root alembic init alembic # create alembic directory alembic revision --autogenerate -m 'initial' # generate migration alembic upgrade head # apply all pending migrations alembic downgrade -1 # roll back one migration alembic history # show migration history alembic current # show current DB version
Quickstart verified last tested: 2026-04-23
# 1. Install and init
# pip install alembic sqlalchemy
# alembic init alembic
# 2. Edit alembic/env.py — add your models:
# from myapp.models import Base
# target_metadata = Base.metadata
# 3. Edit alembic.ini — set database URL:
# sqlalchemy.url = postgresql://user:pass@localhost/mydb
# 4. Generate first migration
# alembic revision --autogenerate -m 'initial schema'
# 5. Apply migration
# alembic upgrade head
# Migration file (alembic/versions/xxx_initial_schema.py):
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table(
'users',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('username', sa.String(50), nullable=False),
sa.Column('email', sa.String(120), nullable=False),
)
def downgrade():
op.drop_table('users')