Alembic is based on SQLAlchemy and serves as a database migration tool with the following functions:

  • ALTER statements to a database to change the structure of tables and other constructs

  • System for creating migration scripts. Optionally, the sequence of steps for the downgrade can also be specified.

  • The scripts are executed in a specific order.

Create migration environment#

The Migration Environment is a directory that is specific to a particular application. It is created with the Alembic ini command and then managed along with the application’s source code.

$ cd myrproject
$ alembic init alembic
Creating directory /path/to/myproject/alembic...done
Creating directory /path/to/myproject/alembic/versions...done
Generating /path/to/myproject/alembic.ini...done
Generating /path/to/myproject/alembic/
Generating /path/to/myproject/alembic/README...done
Generating /path/to/myproject/alembic/
Please edit configuration/connection/logging settings in
'/path/to/myproject/alembic.ini' before proceeding.

The structure of such a migration environment can for example look like this:

└── alembic
    ├── alembic.ini
    ├── README
    └── versions


Alembic includes a number of templates that can be displayed with list:

$ alembic list_templates
Available templates:

generic - Generic single-database configuration.
multidb - Rudimentary multi-database configuration.
pylons - Configuration that reads from a Pylons project environment.

Templates are used via the 'init' command, e.g.:

  alembic init --template pylons ./scripts

Configure ini file#

The file created with the generic template looks like this:

# A generic, single database configuration.

# path to migration scripts
script_location = alembic

# template used to generate migration files
# file_template = %%(rev)s_%%(slug)s

# timezone to use when rendering the date
# within the migration file as well as the filename.
# string value is passed to
# leave blank for localtime
# timezone =

# max length of characters to apply to the
# "slug" field
#truncate_slug_length = 40

# set to 'true' to run the environment during
# the 'revision' command, regardless of autogenerate
# revision_environment = false

# set to 'true' to allow .pyc and .pyo files without
# a source .py file to be detected as revisions in the
# versions/ directory
# sourceless = false

# version location specification; this defaults
# to alembic/versions.  When using multiple version
# directories, initial revisions must be specified with --version-path
# version_locations = %(here)s/bar %(here)s/bat alembic/versions

# the output encoding used when revision files
# are written from
# output_encoding = utf-8

sqlalchemy.url = driver://user:pass@localhost/dbname

# Logging configuration
keys = root,sqlalchemy,alembic

keys = console

keys = generic

level = WARN
handlers = console
qualname =

level = WARN
handlers =
qualname = sqlalchemy.engine

level = INFO
handlers =
qualname = alembic

class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S

Replacement variable for creating absolute paths


This is the naming scheme used to generate new migration files. The available variables include:


Revision ID


Abbreviated revision message

%%(year)d, %%(month).2d, %%(day).2d, %%(hour).2d, %%(minute).2d, %%(second).2d

Creation time

Create a migration script#

A new revision can be created with:

$ alembic revision -m "create account table"
Generating /path/to/yourproject/alembic/versions/

Then the file looks like this:

"""create account table

Revision ID: 1975ea83b712
Create Date: 2018-12-08 11:40:27.089406


# revision identifiers, used by Alembic.
revision = "1975ea83b712"
down_revision = None
branch_labels = None

import sqlalchemy as sa

from alembic import op

def upgrade():

def downgrade():

Variable that tells Alembic in which order the migrations should be carried out, for example:

# revision identifiers, used by Alembic.
revision = "ae1027a6acf"
down_revision = "1975ea83b712"
upgrade, downgrade

for example:

def upgrade():
        sa.Column("id", sa.Integer, primary_key=True),
        sa.Column("name", sa.String(50), nullable=False),
        sa.Column("description", sa.Unicode(200)),

def downgrade():

create_table() and drop_table() are Alembic directives. You can get an overview of all Alembic directives in the Operation Reference.

Run migration#

First migration:

$ alembic upgrade head
INFO  [alembic.context] Context class PostgresqlContext.
INFO  [alembic.context] Will assume transactional DDL.
INFO  [alembic.context] Running upgrade None -> 1975ea83b712

We can also refer directly to revision numbers:

$ alembic upgrade ae1

Relative migrations can also be initiated:

$ alembic upgrade +2


$ alembic downgrade -1


$ alembic upgrade ae10+2

Display Information#

Current version#

$ alembic current
INFO  [alembic.context] Context class PostgresqlContext.
INFO  [alembic.context] Will assume transactional DDL.
Current revision for postgresql://scott:XXXXX@localhost/test: 1975ea83b712 -> ae1027a6acf (head), Add a column


$ alembic history --verbose

Rev: ae1027a6acf (head)
Parent: 1975ea83b712
Path: /path/to/yourproject/alembic/versions/

    add a column

    Revision ID: ae1027a6acf
    Revises: 1975ea83b712
    Create Date: 2014-11-20 13:02:54.849677

Rev: 1975ea83b712
Parent: <base>
Path: /path/to/yourproject/alembic/versions/

    create account table

    Revision ID: 1975ea83b712
    Create Date: 2014-11-20 13:02:46.257104

The history can also be displayed more specifically:

$ alembic history -r1975ea:ae1027


$ alembic history -r-3:current


$ alembic history -r1975ea: