Open-source project
sqlalchemy/alembic avatar
sqlalchemy/alembic

Alembic: SQLAlchemy's migration tool, and when its autogenerate is not enough

A database migrations tool for SQLAlchemy.

4,426 stars383 forksPythonMIT

At a glance

What is it?
Alembic turns schema changes into versioned Python scripts for SQLAlchemy applications. Its autogenerate feature handles the mechanical part of a migration, while the documentation is explicit that real migrations need a human to finish them.
Who is it for?
Adopt Alembic if your schema is defined as SQLAlchemy models or Core tables and you want migrations living in the same repository as that definition. Do not adopt it if you have no SQLAlchemy model to compare against, or if you need fully automatic migration generation, because the project itself describes autogenerate output as candidate migrations that a developer then edits.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 15 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Alembic solves, and who it is written for

Schema changes are the part of application deployment that tends to be done by hand. Alembic addresses that by giving a Python application a versioned sequence of migration scripts. According to the README, each script indicates a series of steps that can upgrade a target database to a new version, and optionally a series of steps that downgrade it by doing the same steps in reverse. Scripts then execute in some sequential manner. The intended user is someone already working with SQLAlchemy, since Alembic is written by SQLAlchemy's author, is distributed as part of the SQLAlchemy Project, and depends on SQLAlchemy 2.0 or newer. The README states the goal plainly: a migrations tool that emits ALTER statements to change the structure of tables. If your schema lives outside SQLAlchemy, the value proposition weakens considerably, because the tool's most useful feature compares a database against a model expressed in Python.

How the migration graph and the environment scripts fit together

Two mechanisms carry most of the design. The first is the environment. A new Alembic setup is generated from a set of templates chosen when setup first occurs, and those templates deposit scripts that define how database connectivity is established and how migration scripts are invoked. Nothing is hidden in a compiled binary; you can edit the generated files. The second is versioning. Scripts are given UUID identifiers in the manner of a distributed version control system, and the linkage from one script to the next lives in human-editable markers inside the scripts. The README describes the collection of migration files as a directed acyclic graph, so any file may depend on any other set, or on none. Branches, multiple roots and merge points are all permitted, and commands exist to create branches, roots and merges. That is a deliberate trade-off: it supports parallel development and long-lived branches, at the cost of a history that is harder to read than a single numbered line. The DDL layer underneath is also usable on its own. The ALTER constructs build on SQLAlchemy's DDLElement base and can be used standalone by any application or script, so you can borrow rename_table() or add_constraint() without adopting the whole migration workflow.

Setting up a migration environment and generating a first script

Alembic installs from PyPI and exposes a console script named alembic, defined in pyproject.toml as alembic.config:main. Python 3.10 or newer is required. Install it into the same environment as your SQLAlchemy application:

bash
pip install alembic

The README states that a new Alembic environment is generated from a set of templates which is selected among a set of options when setup first occurs. The generated files define how database connectivity is established and how migration scripts are invoked, and you edit them to suit your application. Once the environment exists, the autogenerate feature inspects the current status of a database using SQLAlchemy's schema inspection capabilities, compares it to the current state of the database model as specified in Python, and renders candidate migrations into a new migration script as Python directives. The README says the developer then edits the new file, adding additional directives and data migrations as needed, to produce a finished migration. Table and column level changes can be detected, with constraints and indexes to follow as well. For environments where direct DDL access is restricted, the README notes that Alembic's usage model and commands are oriented towards running a series of migrations into a textual output file as easily as it runs them directly to a database, and that bulk_insert() exists as a helper for data-oriented operations compatible with script-based DDL.

Autogenerate produces candidates, not finished migrations

The README is unusually direct about this: real world migrations are far more complex than what can be automatically determined. Table and column level changes can be detected, with constraints and indexes to follow, but the generated file is a starting point. Anything involving data movement, backfills, or a rename that the inspection sees as a drop plus an add has to be written by hand. Treating an autogenerated script as final is the most common way to lose data. There is a second, quieter failure mode around transactional DDL. The default scripts ensure all migrations occur within a transaction, but the README limits the guarantee to databases that support it, naming PostgreSQL and Microsoft SQL Server. On a database without transactional DDL, a migration that fails partway leaves the schema in an intermediate state, and you undo it yourself. SQLite gets separate treatment. Because it cannot ALTER things in the usual way, Alembic offers a batch migration concept, batching multiple changes to a table into a single move-and-copy workflow. The README notes that same workflow can be used on other databases to recreate a table in the background on a busy system, which is a real option but adds a copy of the table's data to the operation.

SQL output mode and the constraint it imposes

Alembic can render migrations to a textual SQL file rather than executing them against a database, which matters where direct DDL access to production is restricted and DBAs want scripts to review. The README describes the usage model and commands as oriented toward running a series of migrations into an output file as easily as running them directly. The catch is stated in the same paragraph: in this mode you must not invoke operations that rely on in-memory SELECTs of rows. Alembic provides bulk_insert() as a helper for data-oriented operations compatible with script-based DDL, but any migration step that reads a value from the database and branches on it will not translate. That rules out a class of migrations people write casually, such as reading a row to compute a new column value. The honest framing is that SQL output mode is a deployment constraint, not a formatting preference, and it changes what your migration scripts are allowed to do.

Alembic against Django migrations and hand-written SQL

Django's migration framework is the closest comparison for a Python web developer, and the difference is architectural rather than cosmetic. Django's migrations are tied to Django's ORM and its model layer; the autodetector, the migration executor and the model state all live inside the framework. Alembic is ORM-agnostic within SQLAlchemy: it compares against SQLAlchemy Core tables or ORM-mapped classes, and the migration environment is a set of editable Python files rather than a framework-managed subsystem. If your application is Django, its own migration tool is already wired into management commands and the test runner, and adding Alembic means maintaining two schema definitions. The other alternative is plain SQL scripts under version control. That approach has no dependency and no learning curve, but it has no graph, no revision identifiers, no downgrade convention, and no way to diff a script against the current model. Alembic's value over hand-written SQL is precisely the comparison step and the ordering metadata.

Maintenance, release cadence and the MIT licence

The repository is not archived, and the last push was on 2026-09-18. Recent releases on the rel_1_20_0 line are dated 2026-09-11, with 1.19.2 on 2026-09-04 and 1.19.1 on 2026-08-08, so this is a project with a steady release rhythm. The declared Python floor is 3.10, and classifiers list support through 3.15 on both CPython and PyPy, which means upgrading Python is unlikely to strand you. Upgrade cost is mostly the cost of reading the changelog: the project maintains one at alembic.sqlalchemy.org, and a migration tool sits in a sensitive place, since a behaviour change in autogenerate can alter the scripts you produce. The dependency set is small (SQLAlchemy, Mako for script templating, typing-extensions, and tomli on Python below 3.11), so Alembic will not drag a large tree into your environment. It is distributed under the MIT licence, which is permissive and imposes no copyleft obligation on your application code; that is a statement about the licence text, not legal advice, and your organisation's own review still governs.

Editorial conclusion

Adopt Alembic if your schema is defined as SQLAlchemy models or Core tables and you want migrations living in the same repository as that definition. Do not adopt it if you have no SQLAlchemy model to compare against, or if you need fully automatic migration generation, because the project itself describes autogenerate output as candidate migrations that a developer then edits. Before committing to it, check two things: whether your database supports transactional DDL, since only then does a failed migration roll back on its own, and whether your deployment process can run the upgrade command rather than hand-edited SQL.

Frequently asked questions

What is Alembic used for?

It is a database migrations tool for SQLAlchemy. It emits ALTER statements to change table structure, builds versioned migration scripts that can upgrade or downgrade a database, and can autogenerate a candidate migration by comparing the database against your SQLAlchemy models.

How to use Alembic?

Generate the migration environment from a template, configure database connectivity in the generated scripts, then create migration scripts and run them in sequence. The README describes the scripts as fully defining how connectivity is established and how migrations are invoked, and they can be customized further.

How to use Alembic with SQLAlchemy?

Alembic is built for SQLAlchemy and depends on SQLAlchemy 2.0 or newer. Its autogenerate feature inspects the current database using SQLAlchemy's schema inspection capabilities and compares it to the database model as specified in Python, rendering candidate migrations into a new script.

How to use Alembic in Python?

The migration environment is generated from templates and consists of editable Python scripts, and each migration script is generated from a template within that series. The scripts define how databases are interacted with and what structure new migration files should take.

How to install Alembic?

Alembic is a Python package distributed from PyPI and declares a console script named alembic. The project requires SQLAlchemy 2.0 or newer, Mako, typing-extensions, and tomli on Python versions below 3.11.

How to install Alembic in Python?

It installs as a normal Python package alongside your SQLAlchemy application, and the project metadata sets the minimum Python version at 3.10. The documentation and status of Alembic are published at alembic.sqlalchemy.org.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. sqlalchemy/alembic on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sqlalchemy-alembic.svg)](https://hysenlabs.com/projects/sqlalchemy-alembic)