Top Banner
Alembic Documentation Release 0.1.2 Mike Bayer January 24, 2012
45

Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Jul 19, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic DocumentationRelease 0.1.2

Mike Bayer

January 24, 2012

Page 2: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration
Page 3: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

CONTENTS

1 Front Matter 31.1 Project Homepage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2 Project Status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.3 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.4 Community . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.5 Bugs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2 Tutorial 52.1 The Migration Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.2 Creating an Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.3 Editing the .ini File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.4 Create a Migration Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82.5 Running our First Migration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.6 Running our Second Migration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.7 Getting Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.8 Downgrading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.9 Auto Generating Migrations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112.10 Generating SQL Scripts (a.k.a. “Offline Mode”) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.11 Working with Branches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.12 Building an Up to Date Database from Scratch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

3 Operation Reference 19

4 API Details 274.1 env.py Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274.2 Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324.3 Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324.4 Internals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

5 Indices and tables 39

Python Module Index 41

i

Page 4: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

ii

Page 5: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

Alembic is a lightweight database migration tool for usage with the SQLAlchemy Database Toolkit for Python.

CONTENTS 1

Page 6: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

2 CONTENTS

Page 7: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

CHAPTER

ONE

FRONT MATTER

Information about the Alembic project.

1.1 Project Homepage

Alembic is hosted on Bitbucket - the lead project page is at https://bitbucket.org/zzzeek/alembic. Source code istracked here using Mercurial.

Releases and project status are available on Pypi at http://pypi.python.org/pypi/alembic.

The most recent published version of this documentation should be at http://alembic.readthedocs.org/.

1.2 Project Status

Note that Alembic is still in alpha status. Users should take care to report bugs and missing features (seeBugs) on an as-needed basis. It should be expected that the development version may be required forproper implementation of recently repaired issues in between releases; the latest tip is always available athttps://bitbucket.org/zzzeek/alembic/get/tip.tar.gz.

1.3 Installation

Install released versions of Alembic from the Python package index with pip or a similar tool:

pip install alembic

Installation via source distribution is via the setup.py script:

python setup.py install

The install will add the alembic command to the environment. All operations with Alembic then proceed throughthe usage of this command.

1.3.1 Dependencies

Alembic’s install process will ensure that SQLAlchemy is installed, in addition to other dependencies. Alembic willwork with SQLAlchemy as of version 0.6, though with a limited featureset. The latest version of SQLAlchemy withinthe 0.7 series is strongly recommended.

3

Page 8: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

1.4 Community

Alembic is developed by Mike Bayer, and is loosely associated with the SQLAlchemy and Pylons projects.

User issues, discussion of potential bugs and features should be posted to the Alembic Google Group at sqlalchemy-alembic.

1.5 Bugs

Bugs and feature enhancements to Alembic should be reported on the Bitbucket issue tracker.

4 Chapter 1. Front Matter

Page 9: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

CHAPTER

TWO

TUTORIAL

Alembic provides for the creation, management, and invocation of change management scripts for a relationaldatabase, using SQLAlchemy as the underlying engine. This tutorial will provide a full introduction to the theoryand usage of this tool.

To begin, make sure Alembic is installed as described at Installation.

2.1 The Migration Environment

Usage of Alembic starts with creation of the Migration Environment. This is a directory of scripts that is specific to aparticular application. The migration environment is created just once, and is then maintained along with the applica-tion’s source code itself. The environment is created using the init command of Alembic, and is then customizableto suit the specific needs of the application.

The structure of this environment, including some generated migration scripts, looks like:

yourproject/alembic/

env.pyREADMEscript.py.makoversions/

3512b954651e.py2b1ae634e5cd.py3adcc9a56557.py

The directory includes these directories/files:

• yourproject - this is the root of your application’s source code, or some directory within it.

• alembic - this directory lives within your application’s source tree and is the home of the migration environ-ment. It can be named anything, and a project that uses multiple databases may even have more than one.

• env.py - This is a Python script that is run whenever the alembic migration tool is invoked. At the very least,it contains instructions to configure and generate a SQLAlchemy engine, procure a connection from that enginealong with a transaction, and to then invoke the migration engine, using the connection as a source of databaseconnectivity.

The env.py script is part of the generated environment so that the way migrations run is entirely customizable.The exact specifics of how to connect are here, as well as the specifics of how the migration enviroment areinvoked. The script can be modified so that multiple engines can be operated upon, custom arguments can bepassed into the migration environment, application-specific libraries and models can be loaded in and madeavailable.

5

Page 10: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

Alembic includes a set of initialization templates which feature different varieties of env.py for different usecases.

• README - included with the various enviromnent templates, should have something informative.

• script.py.mako - This is a Mako template file which is used to generate new migration scripts. Whatever ishere is used to generate new files within versions/. This is scriptable so that the structure of each migrationfile can be controlled, including standard imports to be within each, as well as changes to the structure of theupgrade() and downgrade() functions. For example, the multidb environment allows for multiplefunctions to be generated using a naming scheme upgrade_engine1(), upgrade_engine2().

• versions/ - This directory holds the individual version scripts. Users of other migration tools may noticethat the files here don’t use ascending integers, and instead use a partial GUID approach. In Alembic, theordering of version scripts is relative to directives within the scripts themselves, and it is theoretically possibleto “splice” version files in between others, allowing migration sequences from different branches to be merged,albeit carefully by hand.

2.2 Creating an Environment

With a basic understanding of what the environment is, we can create one using alembic init. This will create anenvironment using the “generic” template:

$ cd yourproject$ alembic init alembic

Where above, the init command was called to generate a migrations directory called alembic:

Creating directory /path/to/yourproject/alembic...doneCreating directory /path/to/yourproject/alembic/versions...doneGenerating /path/to/yourproject/alembic.ini...doneGenerating /path/to/yourproject/alembic/env.py...doneGenerating /path/to/yourproject/alembic/README...doneGenerating /path/to/yourproject/alembic/script.py.mako...donePlease edit configuration/connection/logging settings in’/path/to/yourproject/alembic.ini’ before proceeding.

Alembic also includes other environment templates. These can be listed out using the list_templates command:

$ alembic list_templatesAvailable 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

2.3 Editing the .ini File

Alembic placed a file alembic.ini into the current directory. This is a file that the alembic script looks for wheninvoked. This file can be anywhere, either in the same directory from which the alembic script will normally beinvoked, or if in a different directory, can be specified by using the --config option to the alembic runner.

6 Chapter 2. Tutorial

Page 11: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

The file generated with the “generic” configuration looks like:

# A generic, single database configuration.

[alembic]script_location = %(here)s/alembicsqlalchemy.url = driver://user:pass@localhost/dbname

# Logging configuration[loggers]keys = root,sqlalchemy,alembic

[handlers]keys = console

[formatters]keys = generic

[logger_root]level = WARNhandlers = consolequalname =

[logger_sqlalchemy]level = WARNhandlers =qualname = sqlalchemy.engine

[logger_alembic]level = INFOhandlers =qualname = alembic

[handler_console]class = StreamHandlerargs = (sys.stderr,)level = NOTSETformatter = generic

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

The file is read using Python’s ConfigParser.ConfigParser object. The %(here)s variable is provided asa substitution variable, which can be used to produce absolute pathnames to directories and files, as we do above withthe path to the Alembic script location.

This file contains the following features:

• [alembic] - this is the section read by Alembic to determine configuration. Alembic itself does not directlyread any other areas of the file.

• script_location - this is the location of the Alembic environment, relative to the current directory, unlessthe path is an absolute file path. This is the only key required by Alembic in all cases. The generation of the .inifile by the command alembic init alembic automatically placed the directory name alembic here.

• sqlalchemy.url - A URL to connect to the database via SQLAlchemy. This key is in fact only referencedwithin the env.py file that is specific to the “generic” configuration; a file that can be customized by thedeveloper. A multiple database configuration may respond to multiple keys here, or may reference other sectionsof the file.

2.3. Editing the .ini File 7

Page 12: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

• [loggers], [handlers], [formatters], [logger_*], [handler_*], [formatter_*] - thesesections are all part of Python’s standard logging configuration, the mechanics of which are documented atConfiguration File Format. As is the case with the database connection, these directives are used directly as theresult of the logging.config.fileConfig() call present in the env.py script, which you’re free tomodify.

For starting up with just a single database and the generic configuration, setting up the SQLAlchemy URL is all that’sneeded:

sqlalchemy.url = postgresql://scott:tiger@localhost/test

2.4 Create a Migration Script

With the environment in place we can create a new revision, using alembic revision:

$ alembic revision -m "create account table"Generating /path/to/yourproject/alembic/versions/1975ea83b712.py...done

A new file 1975ea83b712.py is generated. Looking inside the file:

"""create account table

Revision ID: 1975ea83b712Revises: NoneCreate Date: 2011-11-08 11:40:27.089406

"""

# downgrade revision identifier, used by Alembic.down_revision = None

from alembic import opimport sqlalchemy as sa

def upgrade():pass

def downgrade():pass

The file contains some header information, a “downgrade revision identifier”, an import of basic Alembic direc-tives, and empty upgrade() and downgrade() functions. Our job here is to populate the upgrade() anddowngrade() functions with directives that will apply a set of changes to our database. Typically, upgrade() isrequired while downgrade() is only needed if down-revision capability is desired, though it’s probably a good idea.

Another thing to notice is the down_revision variable. This is how Alembic knows the correct order in which toapply migrations. When we create the next revision, the new file’s down_revision identifier would point to thisone:

# downgrade revision identifier, used by Alembic.down_revision = ’1975ea83b712’

Every time Alembic runs an operation against the versions/ directory, it reads all the files in, and composes a listbased on how the down_revision identifiers link together, with the down_revision of None representing thefirst file. In theory, if a migration environment had thousands of migrations, this could begin to add some latency tostartup, but in practice a project should probably prune old migrations anyway (see the section Building an Up to Date

8 Chapter 2. Tutorial

Page 13: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

Database from Scratch for a description on how to do this, while maintaining the ability to build the current databasefully).

We can then add some directives to our script, suppose adding a new table account:

def upgrade():op.create_table(

’account’,sa.Column(’id’, sa.Integer, primary_key=True),sa.Column(’name’, sa.String(50), nullable=False),sa.Column(’description’, sa.Unicode(200)),

)

def downgrade():op.drop_table(’account’)

create_table() and drop_table() are Alembic directives. Alembic provides all the basic database migrationoperations via these directives, which are designed to be as simple and minimalistic as possible; there’s no relianceupon existing table metadata for most of these directives. They draw upon a global “context” that indicates how toget at a database connection (if any; migrations can dump SQL/DDL directives to files as well) in order to invoke thecommand. This global context is set up, like everything else, in the env.py script.

An overview of all Alembic directives is at Operation Reference.

2.5 Running our First Migration

We now want to run our migration. Assuming our database is totally clean, it’s as yet unversioned. The alembicupgrade command will run upgrade operations, proceeding from the current database revision, in this exampleNone, to the given target revision. We can specify 1975ea83b712 as the revision we’d like to upgrade to, but it’seasier in most cases just to tell it “the most recent”, in this case head:

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

Wow that rocked ! Note that the information we see on the screen is the result of the logging configuration set up inalembic.ini - logging the alembic stream to the console (standard error, specifically).

The process which occurred here included that Alembic first checked if the database had a table calledalembic_version, and if not, created it. It looks in this table for the current version, if any, and then calcu-lates the path from this version to the version requested, in this case head, which is known to be 1975ea83b712.It then invokes the upgrade() method in each file to get to the target revision.

2.6 Running our Second Migration

Let’s do another one so we have some things to play with. We again create a revision file:

$ alembic revision -m "Add a column"Generating /path/to/yourapp/alembic/versions/ae1027a6acf.py...done

Let’s edit this file and add a new column to the account table:

"""Add a column

2.5. Running our First Migration 9

Page 14: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

Revision ID: ae1027a6acfRevises: 1975ea83b712Create Date: 2011-11-08 12:37:36.714947

"""

# downgrade revision identifier, used by Alembic.down_revision = ’1975ea83b712’

from alembic import opimport sqlalchemy as sa

def upgrade():op.add_column(’account’, sa.Column(’last_transaction_date’, sa.DateTime))

def downgrade():op.drop_column(’account’, ’last_transaction_date’)

Running again to head:

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

We’ve now added the last_transaction_date column to the database.

2.7 Getting Information

With a few revisions present we can get some information about the state of things.

First we can view the current revision:

$ alembic currentINFO [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

We can also view history:

$ alembic history

1975ea83b712 -> ae1027a6acf (head), Add a columnNone -> 1975ea83b712, empty message

We can also identify specific migrations using just enough characters to uniquely identify them. If we wanted toupgrade directly to ae1027a6acf we could say:

$ alembic upgrade ae1

Alembic will stop and let you know if more than one version starts with that prefix.

2.8 Downgrading

We can illustrate a downgrade back to nothing, by calling alembic downgrade back to the beginning, which inAlembic is called base:

10 Chapter 2. Tutorial

Page 15: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

$ alembic downgrade baseINFO [alembic.context] Context class PostgresqlContext.INFO [alembic.context] Will assume transactional DDL.INFO [alembic.context] Running downgrade ae1027a6acf -> 1975ea83b712INFO [alembic.context] Running downgrade 1975ea83b712 -> None

Back to nothing - and up again:

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

2.9 Auto Generating Migrations

Alembic can view the status of the database and compare against the table metadata in the application, generating the“obvious” migrations based on a comparison. This is achieved using the --autogenerate option to the alembicrevision command, which places so-called candidate migrations into our new migrations file. We review andmodify these by hand as needed, then proceed normally.

To use autogenerate, we first need to modify our env.py so that it gets access to a table metadata object that containsthe target. Suppose our application has a declarative base in myapp.mymodel. This base contains a MetaDataobject which contains Table objects defining our database. We make sure this is loaded in env.py and then passedto context.configure() via the target_metadata argument. The env.py sample script already has avariable declaration near the top for our convenience, where we replace None with our MetaData. Starting with:

# add your model’s MetaData object here# for ’autogenerate’ support# from myapp import mymodel# target_metadata = mymodel.Base.metadatatarget_metadata = None

we change to:

from myapp.mymodel import Basetarget_metadata = Base.metadata

If we look later in the script, down in run_migrations_online(), we can see the directive passed tocontext.configure():

def run_migrations_online():engine = engine_from_config(

config.get_section(config.config_ini_section), prefix=’sqlalchemy.’)

connection = engine.connect()context.configure(

connection=connection,target_metadata=target_metadata)

trans = connection.begin()try:

context.run_migrations()trans.commit()

except:

2.9. Auto Generating Migrations 11

Page 16: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

trans.rollback()raise

We can then use the alembic revision command in conjunction with the --autogenerate option. Supposeour MetaData contained a definition for the account table, and the database did not. We’d get output like:

$ alembic revision --autogenerate -m "Added account table"INFO [alembic.context] Detected added table ’account’Generating /Users/classic/Desktop/tmp/alembic/versions/27c6a30d7c24.py...done

We can then view our file 27c6a30d7c24.py and see that a rudimentary migration is already present:

"""empty message

Revision ID: 27c6a30d7c24Revises: NoneCreate Date: 2011-11-08 11:40:27.089406

"""

# downgrade revision identifier, used by Alembic.down_revision = None

from alembic import opimport sqlalchemy as sa

def upgrade():### commands auto generated by Alembic - please adjust! ###op.create_table(’account’,sa.Column(’id’, sa.Integer()),sa.Column(’name’, sa.String(length=50), nullable=False),sa.Column(’description’, sa.VARCHAR(200)),sa.Column(’last_transaction_date’, sa.DateTime()),sa.PrimaryKeyConstraint(’id’))### end Alembic commands ###

def downgrade():### commands auto generated by Alembic - please adjust! ###op.drop_table("account")### end Alembic commands ###

The migration hasn’t actually run yet, of course. We do that via the usual upgrade command. We should also gointo our migration file and alter it as needed, including adjustments to the directives as well as the addition of otherdirectives which these may be dependent on - specifically data changes in between creates/alters/drops.

Autogenerate will by default detect:

• Table additions, removals.

• Column additions, removals.

• Change of nullable status on columns.

Autogenerate can optionally detect:

• Change of column type. This will occur if you set compare_type=True on context.configure().The feature works well in most cases, but is off by default so that it can be tested on the target schema first. Itcan also be customized by passing a callable here; see the function’s documentation for details.

12 Chapter 2. Tutorial

Page 17: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

• Change of server default. This will occur if you set compare_server_default=True oncontext.configure(). This feature works well for simple cases but cannot always produce accurateresults. The Postgresql backend will actually invoke the “detected” and “metadata” values against the databaseto determine equivalence. The feature is off by default so that it can be tested on the target schema first. Liketype comparison, it can also be customized by passing a callable; see the function’s documentation for details.

Autogenerate can not detect:

• Changes of table name. These will come out as an add/drop of two different tables, and should be hand-editedinto a name change instead.

• Changes of column name. Like table name changes, these are detected as a column add/drop pair, which is notat all the same as a name change.

Autogenerate can’t currently, but will eventually detect:

• Free-standing constraint additions, removals, like CHECK, UNIQUE, FOREIGN KEY - these aren’t yet imple-mented. Right now you’ll get constraints within new tables, PK and FK constraints for the “downgrade” to a pre-viously existing table, and the CHECK constraints generated with a SQLAlchemy “schema” types Boolean,Enum.

• Index additions, removals - not yet implemented.

• Sequence additions, removals - not yet implemented.

2.10 Generating SQL Scripts (a.k.a. “Offline Mode”)

A major capability of Alembic is to generate migrations as SQL scripts, instead of running them against the database- this is also referred to as offline mode. This is a critical feature when working in large organizations where accessto DDL is restricted, and SQL scripts must be handed off to DBAs. Alembic makes this easy via the --sql optionpassed to any upgrade or downgrade command. We can, for example, generate a script that revises up to revae1027a6acf:

$ alembic upgrade ae1027a6acf --sqlINFO [alembic.context] Context class PostgresqlContext.INFO [alembic.context] Will assume transactional DDL.BEGIN;

CREATE TABLE alembic_version (version_num VARCHAR(32) NOT NULL

);

INFO [alembic.context] Running upgrade None -> 1975ea83b712CREATE TABLE account (

id SERIAL NOT NULL,name VARCHAR(50) NOT NULL,description VARCHAR(200),PRIMARY KEY (id)

);

INFO [alembic.context] Running upgrade 1975ea83b712 -> ae1027a6acfALTER TABLE account ADD COLUMN last_transaction_date TIMESTAMP WITHOUT TIME ZONE;

INSERT INTO alembic_version (version_num) VALUES (’ae1027a6acf’);

COMMIT;

2.10. Generating SQL Scripts (a.k.a. “Offline Mode”) 13

Page 18: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

While the logging configuration dumped to standard error, the actual script was dumped to standard output - so in theabsence of further configuration (described later in this section), we’d at first be using output redirection to generate ascript:

$ alembic upgrade ae1027a6acf --sql > migration.sql

2.10.1 Getting the Start Version

Notice that our migration script started at the base - this is the default when using offline mode, as no databaseconnection is present and there’s no alembic_version table to read from.

One way to provide a starting version in offline mode is to provide a range to the command line. This is accomplishedby providing the “version” in start:end syntax:

$ alembic upgrade 1975ea83b712:ae1027a6acf --sql > migration.sql

The start:end syntax is only allowed in offline mode; in “online” mode, the alembic_version table is alwaysused to get at the current version.

It’s also possible to have the env.py script retrieve the “last” version from the local environment, such as from alocal file. A scheme like this would basically treat a local file in the same way alembic_version works:

if context.is_offline_mode():version_file = os.path.join(os.path.dirname(config.config_file_name), "version.txt")if os.path.exists(version_file):

current_version = open(version_file).read()else:

current_version = Nonecontext.configure(dialect_name=engine.name, starting_version=current_version)context.run_migrations()end_version = context.get_revision_argument()if end_version and end_version != current_version:

open(version_file, ’w’).write(end_version)

2.10.2 Writing Migration Scripts to Support Script Generation

The challenge of SQL script generation is that the scripts we generate can’t rely upon any client/server database access.This means a migration script that pulls some rows into memory via a SELECT statement will not work in --sqlmode. It’s also important that the Alembic directives, all of which are designed specifically to work in both “liveexecution” as well as “offline SQL generation” mode, are used.

2.10.3 Customizing the Environment

Users of the --sql option are encouraged to hack their env.py files to suit their needs. The env.py scriptas provided is broken into two sections: run_migrations_online() and run_migrations_offline().Which function is run is determined at the bottom of the script by reading context.is_offline_mode(), whichbasically determines if the --sql flag was enabled.

For example, a multiple database configuration may want to run through each database and set the output of themigrations to different named files - the context.configure() function accepts a parameter output_bufferfor this purpose. Below we illustrate this within the run_migrations_offline() function:

from alembic import contextimport myappimport sys

14 Chapter 2. Tutorial

Page 19: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

db_1 = myapp.db_1db_2 = myapp.db_2

def run_migrations_offline():"""Run migrations *without* a SQL connection."""

for name, engine, file_ in [("db1", db_1, "db1.sql"),("db2", db_2, "db2.sql"),

]:context.configure(

url=engine.url,transactional_ddl=False,output_buffer=open(file_, ’w’))

context.execute("-- running migrations for ’%s’" % name)context.run_migrations(name=name)sys.stderr.write("Wrote file ’%s’" % file_)

def run_migrations_online():"""Run migrations *with* a SQL connection."""

for name, engine in [("db1", db_1),("db2", db_2),

]:connection = engine.connect()context.configure(connection=connection)try:

context.run_migrations(name=name)session.commit()

except:session.rollback()raise

if context.is_offline_mode():run_migrations_offline()

else:run_migrations_online()

2.11 Working with Branches

A branch describes when a source tree is broken up into two versions representing two independent sets of changes.The challenge of a branch is to merge the branches into a single series of changes. Alembic’s GUID-based versionnumber scheme allows branches to be reconciled.

Consider if we merged into our source repository another branch which contained a revision for another table calledshopping_cart. This revision was made against our first Alembic revision, the one that generated account.After loading the second source tree in, a new file 27c6a30d7c24.py exists within our versions directory. Bothit, as well as ae1027a6acf.py, reference 1975ea83b712 as the “downgrade” revision. To illustrate:

# main source tree:1975ea83b712 (add account table) -> ae1027a6acf (add a column)

# branched source tree1975ea83b712 (add account table) -> 27c6a30d7c24 (add shopping cart table)

2.11. Working with Branches 15

Page 20: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

So above we can see 1975ea83b712 is our branch point. The Alembic command branches illustrates this fact:

$ alembic branchesNone -> 1975ea83b712 (branchpoint), add account table

-> 1975ea83b712 -> 27c6a30d7c24 (head), add shopping cart table-> 1975ea83b712 -> ae1027a6acf (head), add a column

History shows it too, illustrating two head entries as well as a branchpoint:

$ alembic history

1975ea83b712 -> 27c6a30d7c24 (head), add shopping cart table

1975ea83b712 -> ae1027a6acf (head), add a columnNone -> 1975ea83b712 (branchpoint), add account table

Alembic will also refuse to run any migrations until this is resolved:

$ alembic upgrade headINFO [alembic.context] Context class PostgresqlContext.INFO [alembic.context] Will assume transactional DDL.Exception: Only a single head supported so far...

We resolve this branch by editing the files to be in a straight line. In this case we edit 27c6a30d7c24.py to pointto ae1027a6acf.py:

"""add shopping cart table

Revision ID: 27c6a30d7c24Revises: ae1027a6acf # changed from 1975ea83b712Create Date: 2011-11-08 13:02:14.212810

"""

# downgrade revision identifier, used by Alembic.# changed from 1975ea83b712down_revision = ’ae1027a6acf’

The branches command then shows no branches:

$ alembic branches$

And the history is similarly linear:

$ alembic history

ae1027a6acf -> 27c6a30d7c24 (head), add shopping cart table1975ea83b712 -> ae1027a6acf, add a columnNone -> 1975ea83b712, add account table

Note: A future command called splice will automate this process.

2.12 Building an Up to Date Database from Scratch

There’s a theory of database migrations that says that the revisions in existence for a database should be able to gofrom an entirely blank schema to the finished product, and back again. Alembic can roll this way. Though we think it’s

16 Chapter 2. Tutorial

Page 21: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

kind of overkill, considering that SQLAlchemy itself can emit the full CREATE statements for any given model usingcreate_all(). If you check out a copy of an application, running this will give you the entire database in oneshot, without the need to run through all those migration files, which are instead tailored towards applying incrementalchanges to an existing database.

Alembic can integrate with a create_all() script quite easily. After running the create operation, tell Alembic tocreate a new version table, and to stamp it with the most recent revision (i.e. head):

# inside of a "create the database" script, first create# tables:my_metadata.create_all(engine)

# then, load the Alembic configuration and generate the# version table, "stamping" it with the most recent rev:from alembic.config import Configfrom alembic import commandalembic_cfg = Config("/path/to/yourapp/alembic.ini")command.stamp(alembic_cfg, "head")

When this approach is used, the application can generate the database using normal SQLAlchemy techniques insteadof iterating through hundreds of migration scripts. Now, the purpose of the migration scripts is relegated just tomovement between versions on out-of-date databases, not new databases. You can now remove old migration files thatare no longer represented on any existing environments.

To prune old migration files, simply delete the files. Then, in the earliest, still-remaining migration file, setdown_revision to None:

# replace this:#down_revision = ’290696571ad2’

# with this:down_revision = None

That file now becomes the “base” of the migration series.

2.12. Building an Up to Date Database from Scratch 17

Page 22: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

18 Chapter 2. Tutorial

Page 23: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

CHAPTER

THREE

OPERATION REFERENCE

This file provides documentation on Alembic migration directives.

The directives here are used within user-defined migration files, within the upgrade() and downgrade() func-tions, as well as any functions further invoked by those.

A key design philosophy to the alembic.op functions is that to the greatest degree possible, they internally generatethe appropriate SQLAlchemy metadata, typically involving Table and Constraint objects. This so that migrationinstructions can be given in terms of just the string names and/or flags involved. The exceptions to this rule include theop.add_column() and op.create_table() directives, which require full Column objects, though the tablemetadata is still generated here.

The functions here all require that a Context has been configured within the env.py script. Under normal cir-cumstances this is always the case, as the migration scripts are invoked via the context.run_migrations()function which ultimately is derived from the Context object.

alembic.op.add_column(table_name, column)Issue an “add column” instruction using the current change context.

e.g.:

from alembic.op import add_columnfrom sqlalchemy import Column, String

add_column(’organization’,Column(’name’, String())

)

The provided Column object can also specify a ForeignKey, referencing a remote table name. Alembicwill automatically generate a stub “referenced” table and emit a second ALTER statement in order to add theconstraint separately:

from alembic.op import add_columnfrom sqlalchemy import Column, INTEGER, ForeignKey

add_column(’organization’,Column(’account_id’, INTEGER, ForeignKey(’accounts.id’))

)

Parameters

• table_name – String name of the parent table.

• column – a sqlalchemy.schema.Column object representing the new column.

19

Page 24: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

alembic.op.alter_column(table_name, column_name, nullable=None, server_default=False,name=None, type_=None, existing_type=None, exist-ing_server_default=False, existing_nullable=None)

Issue an “alter column” instruction using the current change context.

Generally, only that aspect of the column which is being changed, i.e. name, type, nullability, default, needsto be specified. Multiple changes can also be specified at once and the backend should “do the right thing”,emitting each change either separately or together as the backend allows.

MySQL has special requirements here, since MySQL cannot ALTER a column without a full specifica-tion. When producing MySQL-compatible migration files, it is recommended that the existing_type,existing_server_default, and existing_nullable parameters be present, if not being altered.

Type changes which are against the SQLAlchemy “schema” types Boolean and Enum may also addor drop constraints which accompany those types on backends that don’t support them natively. Theexisting_server_default argument is used in this case as well to remove a previous constraint.

Parameters

• table_name – string name of the target table.

• column_name – string name of the target column, as it exists before the operation begins.

• nullable – Optional; specify True or False to alter the column’s nullability.

• server_default – Optional; specify a string SQL expression, text(), orDefaultClause to indicate an alteration to the column’s default value. Set toNone to have the default removed.

• name – Optional; specify a string name here to indicate the new name within a columnrename operation.

• type – Optional; a TypeEngine type object to specify a change to the column’s type. ForSQLAlchemy types that also indicate a constraint (i.e. Boolean, Enum), the constraint isalso generated.

• existing_type – Optional; a TypeEngine type object to specify the previous type. Thisis required for all MySQL column alter operations that don’t otherwise specify a new type,as well as for when nullability is being changed on a SQL Server column. It is also usedif the type is a so-called SQLlchemy “schema” type which may define a constraint (i.e.Boolean, Enum), so that the constraint can be dropped.

• existing_server_default – Optional; The existing default value of the column. Required onMySQL if an existing default is not being changed; else MySQL removes the default.

• existing_nullable – Optional; the existing nullability of the column. Required on MySQLif the existing nullability is not being changed; else MySQL sets this to NULL.

alembic.op.bulk_insert(table, rows)Issue a “bulk insert” operation using the current change context.

This provides a means of representing an INSERT of multiple rows which works equally well in the context ofexecuting on a live connection as well as that of generating a SQL script. In the case of a SQL script, the valuesare rendered inline into the statement.

e.g.:

from datetime import datefrom sqlalchemy.sql import table, columnfrom sqlalchemy import String, Integer, Date

# Create an ad-hoc table to use for the insert statement.accounts_table = table(’account’,

20 Chapter 3. Operation Reference

Page 25: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

column(’id’, Integer),column(’name’, String),column(’create_date’, Date)

)

bulk_insert(accounts_table,[

{’id’:1, ’name’:’John Smith’, ’create_date’:date(2010, 10, 5)},{’id’:2, ’name’:’Ed Williams’, ’create_date’:date(2007, 5, 27)},{’id’:3, ’name’:’Wendy Jones’, ’create_date’:date(2008, 8, 15)},

])

alembic.op.create_check_constraint(name, source, condition, **kw)Issue a “create check constraint” instruction using the current change context.

e.g.:

from alembic.op import create_check_constraintfrom sqlalchemy.sql import column, func

create_check_constraint("ck_user_name_len","user",func.len(column(’name’)) > 5

)

CHECK constraints are usually against a SQL expression, so ad-hoc table metadata is usually needed. Thefunction will convert the given arguments into a sqlalchemy.schema.CheckConstraint bound to ananonymous table in order to emit the CREATE statement.

Parameters

• name – Name of the check constraint. The name is necessary so that an ALTER statementcan be emitted. For setups that use an automated naming scheme such as that described atNamingConventions, name here can be None, as the event listener will apply the name tothe constraint object when it is associated with the table.

• source – String name of the source table. Currently there is no support for dotted schemanames.

• condition – SQL expression that’s the condition of the constraint. Can be a string orSQLAlchemy expression language structure.

• deferrable – optional bool. If set, emit DEFERRABLE or NOT DEFERRABLE whenissuing DDL for this constraint.

• initially – optional string. If set, emit INITIALLY <value> when issuing DDL for thisconstraint.

alembic.op.create_foreign_key(name, source, referent, local_cols, remote_cols)Issue a “create foreign key” instruction using the current change context.

e.g.:

from alembic.op import create_foreign_keycreate_foreign_key("fk_user_address", "address", "user", ["user_id"], ["id"])

This internally generates a Table object containing the necessary columns, then generates a newForeignKeyConstraint object which it then associates with the Table. Any event listeners associated

21

Page 26: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

with this action will be fired off normally. The AddConstraint construct is ultimately used to generate theALTER statement.

Parameters

• name – Name of the foreign key constraint. The name is necessary so that an ALTERstatement can be emitted. For setups that use an automated naming scheme such as thatdescribed at NamingConventions, name here can be None, as the event listener will applythe name to the constraint object when it is associated with the table.

• source – String name of the source table. Currently there is no support for dotted schemanames.

• referent – String name of the destination table. Currently there is no support for dottedschema names.

• local_cols – a list of string column names in the source table.

• remote_cols – a list of string column names in the remote table.

alembic.op.create_index(name, tablename, *columns, **kw)Issue a “create index” instruction using the current change context.

e.g.:

from alembic.op import create_indexcreate_index(’ik_test’, ’t1’, [’foo’, ’bar’])

alembic.op.create_table(name, *columns, **kw)Issue a “create table” instruction using the current change context.

This directive receives an argument list similar to that of the traditional sqlalchemy.schema.Table con-struct, but without the metadata:

from sqlalchemy import INTEGER, VARCHAR, NVARCHAR, Columnfrom alembic.op import create_table

create_table(’accounts’,Column(’id’, INTEGER, primary_key=True),Column(’name’, VARCHAR(50), nullable=False),Column(’description’, NVARCHAR(200))

)

Parameters

• name – Name of the table

• *columns – collection of Column objects within the table, as well as optionalConstraint objects and Index objects.

• emit_events – if True, emit before_create and after_create events when thetable is being created. In particular, the Postgresql ENUM type will emit a CREATE TYPEwithin these events.

• **kw – Other keyword arguments are passed to the underlying Table object created forthe command.

alembic.op.create_unique_constraint(name, source, local_cols, **kw)Issue a “create unique constraint” instruction using the current change context.

e.g.:

22 Chapter 3. Operation Reference

Page 27: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

from alembic.op import create_unique_constraintcreate_unique_constraint("uq_user_name", "user", ["name"])

This internally generates a Table object containing the necessary columns, then generates a newUniqueConstraint object which it then associates with the Table. Any event listeners associated with thisaction will be fired off normally. The AddConstraint construct is ultimately used to generate the ALTERstatement.

Parameters

• name – Name of the unique constraint. The name is necessary so that an ALTER statementcan be emitted. For setups that use an automated naming scheme such as that described atNamingConventions, name here can be None, as the event listener will apply the name tothe constraint object when it is associated with the table.

• source – String name of the source table. Currently there is no support for dotted schemanames.

• local_cols – a list of string column names in the source table.

• deferrable – optional bool. If set, emit DEFERRABLE or NOT DEFERRABLE whenissuing DDL for this constraint.

• initially – optional string. If set, emit INITIALLY <value> when issuing DDL for thisconstraint.

alembic.op.drop_column(table_name, column_name, **kw)Issue a “drop column” instruction using the current change context.

e.g.:

drop_column(’organization’, ’account_id’)

Parameters

• table_name – name of table

• column_name – name of column

• mssql_drop_check – Optional boolean. When True, on Microsoft SQL Server only, firstdrop the CHECK constraint on the column using a SQL-script-compatible block that selectsinto a @variable from sys.check_constraints, then exec’s a separate DROP CONSTRAINTfor that constraint.

• mssql_drop_default – Optional boolean. When True, on Microsoft SQL Server only,first drop the DEFAULT constraint on the column using a SQL-script-compatible blockthat selects into a @variable from sys.default_constraints, then exec’s a separate DROPCONSTRAINT for that default.

alembic.op.drop_constraint(name, tablename)Drop a constraint of the given name

alembic.op.drop_index(name)Issue a “drop index” instruction using the current change context.

e.g.:

drop_index("accounts")

alembic.op.drop_table(name)Issue a “drop table” instruction using the current change context.

23

Page 28: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

e.g.:

drop_table("accounts")

alembic.op.execute(sql)Execute the given SQL using the current change context.

In a SQL script context, the statement is emitted directly to the output stream. There is no return result, however,as this function is oriented towards generating a change script that can run in “offline” mode. For full interactionwith a connected database, use the “bind” available from the context:

from alembic.op import get_bindconnection = get_bind()

Also note that any parameterized statement here will not work in offline mode - INSERT, UPDATE and DELETEstatements which refer to literal values would need to render inline expressions. For simple use cases, theinline_literal() function can be used for rudimentary quoting of string values. For “bulk” inserts,consider using bulk_insert().

For example, to emit an UPDATE statement which is equally compatible with both online and offline mode:

from sqlalchemy.sql import table, columnfrom sqlalchemy import Stringfrom alembic.op import execute, inline_literal

account = table(’account’,column(’name’, String)

)execute(

account.update().\where(account.c.name==inline_literal(’account 1’)).\values({’name’:inline_literal(’account 2’)}))

Note above we also used the SQLAlchemy sqlalchemy.sql.expression.table() andsqlalchemy.sql.expression.column() constructs to make a brief, ad-hoc table construct justfor our UPDATE statement. A full Table construct of course works perfectly fine as well, though note it’s arecommended practice to at least ensure the definition of a table is self-contained within the migration script,rather than imported from a module that may break compatibility with older migrations.

Parameters sql – Any legal SQLAlchemy expression, including:

•a string

•a sqlalchemy.sql.expression.text() construct.

•a sqlalchemy.sql.expression.insert() construct.

•a sqlalchemy.sql.expression.update(), sqlalchemy.sql.expression.insert(),or sqlalchemy.sql.expression.delete() construct.

•Pretty much anything that’s “executable” as described in SQL Expression Language Tutorial.

alembic.op.get_bind()Return the current ‘bind’.

Under normal circumstances, this is the sqlalchemy.engine.Connection currently being used to emitSQL to the database.

In a SQL script context, this value is None. [TODO: verify this]

24 Chapter 3. Operation Reference

Page 29: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

alembic.op.get_context()Return the current Context object.

If configure() has not been called yet, raises an exception.

Generally, env.py scripts should access the module-level functions in alebmic.context to get at this object’sfunctionality.

alembic.op.inline_literal(value, type_=None)Produce an ‘inline literal’ expression, suitable for using in an INSERT, UPDATE, or DELETE statement.

When using Alembic in “offline” mode, CRUD operations aren’t compatible with SQLAlchemy’s default be-havior surrounding literal values, which is that they are converted into bound values and passed separately intothe execute() method of the DBAPI cursor. An offline SQL script needs to have these rendered inline. Whileit should always be noted that inline literal values are an enormous security hole in an application that handlesuntrusted input, a schema migration is not run in this context, so literals are safe to render inline, with the caveatthat advanced types like dates may not be supported directly by SQLAlchemy.

See op.execute() for an example usage of inline_literal().

Parameters

• value – The value to render. Strings, integers, and simple numerics should be supported.Other types like boolean, dates, etc. may or may not be supported yet by various backends.

• type – optional - a sqlalchemy.types.TypeEngine subclass stating the type of thisvalue. In SQLAlchemy expressions, this is usually derived automatically from the Pythontype of the value itself, as well as based on the context in which the value is used.

alembic.op.rename_table(old_table_name, new_table_name, schema=None)Emit an ALTER TABLE to rename a table.

Parameters

• old_table_name – old name.

• new_table_name – new name.

• schema – Optional, name of schema to operate within.

25

Page 30: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

26 Chapter 3. Operation Reference

Page 31: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

CHAPTER

FOUR

API DETAILS

This section describes some key functions used within the migration process, particularly those referenced within amigration environment’s env.py file.

4.1 env.py Directives

The alembic.context module contains API features that are generally used within env.py files.

The central object in use is the Context object. This object is made present when the env.py script calls uponthe configure() method for the first time. Before this function is called, there’s not yet any database connectionor dialect-specific state set up, and those functions which require this state will raise an exception when used, untilconfigure() is called successfully.

sqlalchemy.engine.engine_from_config(configuration, prefix=’sqlalchemy.’, **kwargs)Create a new Engine instance using a configuration dictionary.

The dictionary is typically produced from a config file where keys are prefixed, such as sqlalchemy.url,sqlalchemy.echo, etc. The ‘prefix’ argument indicates the prefix to be searched for.

A select set of keyword arguments will be “coerced” to their expected type based on string values. In a futurerelease, this functionality will be expanded and include dialect-specific arguments.

class alembic.context.Context(dialect, script, connection, fn, as_sql=False, output_buffer=None,transactional_ddl=None, starting_rev=None, compare_type=False,compare_server_default=False)

Maintains state throughout the migration running process.

Mediates the relationship between an env.py environment script, a ScriptDirectory instance, and aDefaultImpl instance.

The Context is available directly via the get_context() function, though usually it is referenced behindthe scenes by the various module level functions within the alembic.context module.

bindReturn the current “bind”.

In online mode, this is an instance of sqlalchemy.engine.base.Connection, andis suitable for ad-hoc execution of any kind of usage described in SQL Expression Lan-guage Tutorial as well as for usage with the sqlalchemy.schema.Table.create() andsqlalchemy.schema.MetaData.create_all() methods of Table, MetaData.

Note that when “standard output” mode is enabled, this bind will be a “mock” connection handler thatcannot return results and is only appropriate for a very limited subset of commands.

27

Page 32: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

alembic.context.begin_transaction()Return a context manager that will enclose an operation within a “transaction”, as defined by the environment’soffline and transactional DDL settings.

e.g.:

with context.begin_transaction():context.run_migrations()

begin_transaction() is intended to “do the right thing” regardless of calling context:

•If is_transactional_ddl() is False, returns a “do nothing” context manager which otherwiseproduces no transactional state or directives.

•If is_offline_mode() is True, returns a context manager that will invoke theDefaultImpl.emit_begin() and DefaultImpl.emit_commit() methods, which willproduce the string directives BEGIN and COMMIT on the output stream, as rendered by the target backend(e.g. SQL Server would emit BEGIN TRANSACTION).

•Otherwise, calls sqlalchemy.engine.base.Connection.begin() on the current online con-nection, which returns a sqlalchemy.engine.base.Transaction object. This object demar-cates a real transaction and is itself a context manager, which will roll back if an exception is raised.

Note that a custom env.py script which has more specific transactional needs can of course manipulate theConnection directly to produce transactional state in “online” mode.

alembic.context.config = NoneThe current Config object.

This is the gateway to the alembic.ini or other .ini file in use for the current command.

This function does not require that the Context has been configured.

alembic.context.configure(connection=None, url=None, dialect_name=None, transac-tional_ddl=None, output_buffer=None, starting_rev=None,tag=None, target_metadata=None, compare_type=False, com-pare_server_default=False, upgrade_token=’upgrades’, down-grade_token=’downgrades’, alembic_module_prefix=’op.’,sqlalchemy_module_prefix=’sa.’, **kw)

Configure the migration environment.

The important thing needed here is first a way to figure out what kind of “dialect” is in use. The second is topass an actual database connection, if one is required.

If the is_offline_mode() function returns True, then no connection is needed here. Otherwise, theconnection parameter should be present as an instance of sqlalchemy.engine.base.Connection.

This function is typically called from the env.py script within a migration environment. It can be calledmultiple times for an invocation. The most recent Connection for which it was called is the one that will beoperated upon by the next call to run_migrations().

General parameters:

Parameters

• connection – a Connection to use for SQL execution in “online” mode. When present,is also used to determine the type of dialect in use.

• url – a string database url, or a sqlalchemy.engine.url.URL object. The type ofdialect to be used will be derived from this if connection is not passed.

• dialect_name – string name of a dialect, such as “postgresql”, “mssql”, etc. The type ofdialect to be used will be derived from this if connection and url are not passed.

28 Chapter 4. API Details

Page 33: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

• transactional_ddl – Force the usage of “transactional” DDL on or off; this otherwise de-faults to whether or not the dialect in use supports it.

• output_buffer – a file-like object that will be used for textual output when the --sqloption is used to generate SQL scripts. Defaults to sys.stdout if not passed here andalso not present on the Config object. The value here overrides that of the Config object.

• starting_rev – Override the “starting revision” argument when using --sql mode.

• tag – a string tag for usage by custom env.py scripts. Set via the --tag option, can beoverridden here.

Parameters specific to the autogenerate feature, when alembic revision is run with the--autogenerate feature:

Parameters

• target_metadata – a sqlalchemy.schema.MetaData object that will be consultedduring autogeneration. The tables present will be compared against what is locally availableon the target Connection to produce candidate upgrade/downgrade operations.

• compare_type – Indicates type comparison behavior during an autogenerate operation. De-faults to False which disables type comparison. Set to True to turn on default typecomparison, which has varied accuracy depending on backend.

To customize type comparison behavior, a callable may be specified which can filter typecomparisons during an autogenerate operation. The format of this callable is:

def my_compare_type(context, inspected_column,metadata_column, inspected_type, metadata_type):

# return True if the types are different,# False if not, or None to allow the default implementation# to compare these typespass

inspected_column is a dictionary structure as returned bysqlalchemy.engine.reflection.Inspector.get_columns(), whereasmetadata_column is a sqlalchemy.schema.Column from the local modelenvironment.

A return value of None indicates to allow default type comparison to proceed.

• compare_server_default – Indicates server default comparison behavior during an auto-generate operation. Defaults to False which disables server default comparison. Set toTrue to turn on server default comparison, which has varied accuracy depending on back-end.

To customize server default comparison behavior, a callable may be specified which canfilter server default comparisons during an autogenerate operation. defaults during an auto-generate operation. The format of this callable is:

def my_compare_server_default(context, inspected_column,metadata_column, inspected_default, metadata_default,rendered_metadata_default):

# return True if the defaults are different,# False if not, or None to allow the default implementation# to compare these defaultspass

4.1. env.py Directives 29

Page 34: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

inspected_column is a dictionary structure as returned bysqlalchemy.engine.reflection.Inspector.get_columns(), whereasmetadata_column is a sqlalchemy.schema.Column from the local modelenvironment.

A return value of None indicates to allow default server default comparison to proceed.Note that some backends such as Postgresql actually execute the two defaults on the databaseside to compare for equivalence.

• upgrade_token – When autogenerate completes, the text of the candidate upgrade opera-tions will be present in this template variable when script.py.mako is rendered. De-faults to upgrades.

• downgrade_token – When autogenerate completes, the text of the candidate downgradeoperations will be present in this template variable when script.py.mako is rendered.Defaults to downgrades.

• alembic_module_prefix – When autogenerate refers to Alembic alembic.op constructs,this prefix will be used (i.e. op.create_table) Defaults to “op.”. Can be None toindicate no prefix.

• sqlalchemy_module_prefix – When autogenerate refers to SQLAlchemy Column or typeclasses, this prefix will be used (i.e. sa.Column("somename", sa.Integer)) De-faults to “sa.”. Can be None to indicate no prefix. Note that when dialect-specifictypes are rendered, autogenerate will render them using the dialect module name, i.e.mssql.BIT(), postgresql.UUID().

Parameters specific to individual backends:

Parameters mssql_batch_separator – The “batch separator” which will be placed between eachstatement when generating offline SQL Server migrations. Defaults to GO. Note this is in addi-tion to the customary semicolon ; at the end of each statement; SQL Server considers the “batchseparator” to denote the end of an individual statement execution, and cannot group certain de-pendent operations in one step.

alembic.context.configure_connection(connection)Deprecated; use alembic.context.configure().

alembic.context.execute(sql)Execute the given SQL using the current change context.

The behavior of context.execute() is the same as that of op.execute(). Please see that function’sdocumentation for full detail including caveats and limitations.

This function requires that a Context has first been made available via configure().

alembic.context.get_bind()Return the current ‘bind’.

In “online” mode, this is the sqlalchemy.engine.Connection currently being used to emit SQL to thedatabase.

This function requires that a Context has first been made available via configure().

alembic.context.get_context()Return the current Context object.

If configure() has not been called yet, raises an exception.

Generally, env.py scripts should access the module-level functions in alebmic.context to get at this object’sfunctionality.

30 Chapter 4. API Details

Page 35: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

alembic.context.get_head_revision()Return the hex identifier of the ‘head’ revision.

This function does not require that the Context has been configured.

alembic.context.get_revision_argument()Get the ‘destination’ revision argument.

This is typically the argument passed to the upgrade or downgrade command.

If it was specified as head, the actual version number is returned; if specified as base, None is returned.

This function does not require that the Context has been configured.

alembic.context.get_starting_revision_argument()Return the ‘starting revision’ argument, if the revision was passed using start:end.

This is only meaningful in “offline” mode. Returns None if no value is available or was configured.

This function does not require that the Context has been configured.

alembic.context.get_tag_argument()Return the value passed for the --tag argument, if any.

The --tag argument is not used directly by Alembic, but is available for custom env.py configurations thatwish to use it; particularly for offline generation scripts that wish to generate tagged filenames.

This function does not require that the Context has been configured.

alembic.context.is_offline_mode()Return True if the current migrations environment is running in “offline mode”.

This is True or False depending on the the --sql flag passed.

This function does not require that the Context has been configured.

alembic.context.is_transactional_ddl()Return True if the context is configured to expect a transactional DDL capable backend.

This defaults to the type of database in use, and can be overridden by the transactional_ddl argument toconfigure()

This function requires that a Context has first been made available via configure().

alembic.context.run_migrations(**kw)Run migrations as determined by the current command line configuration as well as versioning informationpresent (or not) in the current database connection (if one is present).

The function accepts optional **kw arguments. If these are passed, they are sent directly to the upgrade()and downgrade() functions within each target revision file. By modifying the script.py.mako file sothat the upgrade() and downgrade() functions accept arguments, parameters can be passed here so thatcontextual information, usually information to identify a particular database in use, can be passed from a customenv.py script to the migration functions.

This function requires that a Context has first been made available via configure().

alembic.context.static_output(text)Emit text directly to the “offline” SQL stream.

Typically this is for emitting comments that start with –. The statement is not treated as a SQL execution, no ;or batch separator is added, etc.

4.1. env.py Directives 31

Page 36: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

4.2 Commands

Alembic commands are all represented by functions in the alembic.command package. They all accept the samestyle of usage, being sent the Config object as the first argument.

Commands can be run programmatically, by first constructing a Config object, as in:

from alembic.config import Configfrom alembic import commandalembic_cfg = Config("/path/to/yourapp/alembic.ini")command.upgrade(alembic_cfg, "head")

alembic.command.branches(config)Show current un-spliced branch points

alembic.command.current(config)Display the current revision for each database.

alembic.command.downgrade(config, revision, sql=False, tag=None)Revert to a previous version.

alembic.command.history(config)List changeset scripts in chronological order.

alembic.command.init(config, directory, template=’generic’)Initialize a new scripts directory.

alembic.command.list_templates(config)List available templates

alembic.command.revision(config, message=None, autogenerate=False)Create a new revision file.

alembic.command.splice(config, parent, child)‘splice’ two branches, creating a new revision file.

this command isn’t implemented right now.

alembic.command.stamp(config, revision, sql=False, tag=None)‘stamp’ the revision table with the given revision; don’t run any migrations.

alembic.command.upgrade(config, revision, sql=False, tag=None)Upgrade to a later version.

4.3 Configuration

class alembic.config.Config(file_=None, ini_section=’alembic’, output_buffer=None)Represent an Alembic configuration.

Within an env.py script, this is available via the alembic.context.config attribute:

from alembic import context

some_param = context.config.get_main_option("my option")

When invoking Alembic programatically, a new Config can be created by passing the name of an .ini file tothe constructor:

32 Chapter 4. API Details

Page 37: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

from alembic.config import Configalembic_cfg = Config("/path/to/yourapp/alembic.ini")

With a Config object, you can then run Alembic commands programmatically using the directives inalembic.command.

The Config object can also be constructed without a filename. Values can be set programmatically, and newsections will be created as needed:

from alembic.config import Configalembic_cfg = Config()alembic_cfg.set_main_option("url", "postgresql://foo/bar")alembic_cfg.set_section_option("mysection", "foo", "bar")

Parameters

• file – name of the .ini file to open.

• ini_section – name of the main Alembic section within the .ini file

• output_buffer – optional file-like input buffer which will be passed to the Context - usedto redirect access when using Alembic programmatically.

config_file_name = NoneFilesystem path to the .ini file in use.

config_ini_section = NoneName of the config file section to read basic configuration from. Defaults to alembic, that is the[alembic] section of the .ini file. This value is modified using the -n/--name option to the Alembicrunnier.

file_config = None

get_main_option(name, default=None)Return an option from the ‘main’ section of the .ini file.

This defaults to being a key from the [alembic] section, unless the -n/--name flag were used toindicate a different section.

get_section(name)Return all the configuration options from a given .ini file section as a dictionary.

get_section_option(section, name, default=None)Return an option from the given section of the .ini file.

get_template_directory()Return the directory where Alembic setup templates are found.

This method is used by the alembic init and list_templates commands.

set_main_option(name, value)Set an option programmatically within the ‘main’ section.

This overrides whatever was in the .ini file.

set_section_option(section, name, value)Set an option programmatically within the given section.

The section is created if it doesn’t exist already. The value here will override whatever was in the .ini file.

alembic.config.main(argv=None, **kwargs)The console runner function for Alembic.

4.3. Configuration 33

Page 38: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

4.4 Internals

class alembic.script.Script(module, rev_id)Represent a single revision file in a versions/ directory.

add_nextrev(rev)

doc

classmethod from_filename(dir_, filename)

classmethod from_path(path)

is_branch_point

is_head

nextrev = frozenset([])

class alembic.script.ScriptDirectory(dir)Provides operations upon an Alembic script directory.

copy_file(src, dest)

downgrade_to(destination, current_rev)

env_py_location

classmethod from_config(config)

generate_rev(revid, message, refresh=False, **kw)

generate_template(src, dest, **kw)

run_env()Run the script environment.

This basically runs the env.py script present in the migration environment. It is called exclusively by thecommand functions in alembic.command.

As env.py runs context.configure_connection(), the connection environment should be setup first. This is typically achieved using the context.opts().

upgrade_from(destination, current_rev)

walk_revisions()Iterate through all revisions.

This is actually a breadth-first tree traversal, with leaf nodes being heads.

write(rev_id, content)

4.4.1 DDL Internals

class alembic.ddl.base.AddColumn(name, column, schema=None)

class alembic.ddl.base.AlterColumn(name, column_name, schema=None, existing_type=None, ex-isting_nullable=None, existing_server_default=None)

class alembic.ddl.base.AlterTable(table_name, schema=None)Represent an ALTER TABLE statement.

Only the string name and optional schema name of the table is required, not a full Table object.

class alembic.ddl.base.ColumnDefault(name, column_name, default, **kw)

34 Chapter 4. API Details

Page 39: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

class alembic.ddl.base.ColumnName(name, column_name, newname, **kw)

class alembic.ddl.base.ColumnNullable(name, column_name, nullable, **kw)

class alembic.ddl.base.ColumnType(name, column_name, type_, **kw)

class alembic.ddl.base.DropColumn(name, column, schema=None)

class alembic.ddl.base.RenameTable(old_table_name, new_table_name, schema=None)

alembic.ddl.base.add_column(compiler, column, **kw)

alembic.ddl.base.alter_column(compiler, name)

alembic.ddl.base.alter_table(compiler, name, schema)

alembic.ddl.base.drop_column(compiler, name)

alembic.ddl.base.format_column_name(compiler, name)

alembic.ddl.base.format_server_default(compiler, default)

alembic.ddl.base.format_table_name(compiler, name, schema)

alembic.ddl.base.format_type(compiler, type_)

alembic.ddl.base.quote_dotted(name, quote)quote the elements of a dotted name

alembic.ddl.base.visit_add_column(element, compiler, **kw)

alembic.ddl.base.visit_column_default(element, compiler, **kw)

alembic.ddl.base.visit_column_name(element, compiler, **kw)

alembic.ddl.base.visit_column_nullable(element, compiler, **kw)

alembic.ddl.base.visit_column_type(element, compiler, **kw)

alembic.ddl.base.visit_drop_column(element, compiler, **kw)

alembic.ddl.base.visit_rename_table(element, compiler, **kw)

class alembic.ddl.impl.DefaultImpl(dialect, connection, as_sql, transactional_ddl, output_buffer,context_opts)

Provide the entrypoint for major migration operations, including database-specific behavioral variances.

While individual SQL/DDL constructs already provide for database-specific implementations, variances hereallow for entirely different sequences of operations to take place for a particular migration, such as SQL Server’sspecial ‘IDENTITY INSERT’ step for bulk inserts.

add_column(table_name, column)

add_constraint(const)

alter_column(table_name, column_name, nullable=None, server_default=False, name=None,type_=None, schema=None, existing_type=None, existing_server_default=None, ex-isting_nullable=None)

bind

bulk_insert(table, rows)

compare_server_default(inspector_column, metadata_column, rendered_metadata_default)

compare_type(inspector_column, metadata_column)

create_index(index)

create_table(table)

4.4. Internals 35

Page 40: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

drop_column(table_name, column, **kw)

drop_constraint(const)

drop_index(index)

drop_table(table)

emit_begin()Emit the string BEGIN, or the backend-specific equivalent, on the current connection context.

This is used in offline mode and typically via context.begin_transaction().

emit_commit()Emit the string COMMIT, or the backend-specific equivalent, on the current connection context.

This is used in offline mode and typically via context.begin_transaction().

execute(sql)

classmethod get_by_dialect(dialect)

rename_table(old_table_name, new_table_name, schema=None)

start_migrations()A hook called when Context.run_migrations() is called.

Implementations can set up per-migration-run state here.

static_output(text)

transactional_ddl = False

class alembic.ddl.impl.ImplMeta(classname, bases, dict_)

MySQL

class alembic.ddl.mysql.MySQLAlterColumn(name, column_name, schema=None, new-name=None, type_=None, nullable=None, de-fault=False)

Bases: alembic.ddl.base.AlterColumn

class alembic.ddl.mysql.MySQLImpl(dialect, connection, as_sql, transactional_ddl, output_buffer,context_opts)

Bases: alembic.ddl.impl.DefaultImpl

alter_column(table_name, column_name, nullable=None, server_default=False, name=None,type_=None, schema=None, existing_type=None, existing_server_default=None, ex-isting_nullable=None)

MS-SQL

class alembic.ddl.mssql.MSSQLImpl(*arg, **kw)Bases: alembic.ddl.impl.DefaultImpl

alter_column(table_name, column_name, nullable=None, server_default=False, name=None,type_=None, schema=None, existing_type=None, existing_server_default=None, ex-isting_nullable=None)

batch_separator = ‘GO’

bulk_insert(table, rows)

drop_column(table_name, column, **kw)

36 Chapter 4. API Details

Page 41: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

emit_begin()

transactional_ddl = True

alembic.ddl.mssql.mssql_add_column(compiler, column, **kw)

alembic.ddl.mssql.visit_add_column(element, compiler, **kw)

alembic.ddl.mssql.visit_column_default(element, compiler, **kw)

alembic.ddl.mssql.visit_column_nullable(element, compiler, **kw)

alembic.ddl.mssql.visit_column_type(element, compiler, **kw)

alembic.ddl.mssql.visit_rename_column(element, compiler, **kw)

Postgresql

class alembic.ddl.postgresql.PostgresqlImpl(dialect, connection, as_sql, transactional_ddl,output_buffer, context_opts)

Bases: alembic.ddl.impl.DefaultImpl

compare_server_default(inspector_column, metadata_column, rendered_metadata_default)

transactional_ddl = True

SQLite

class alembic.ddl.sqlite.SQLiteImpl(dialect, connection, as_sql, transactional_ddl, out-put_buffer, context_opts)

Bases: alembic.ddl.impl.DefaultImpl

transactional_ddl = True

4.4. Internals 37

Page 42: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

38 Chapter 4. API Details

Page 43: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

CHAPTER

FIVE

INDICES AND TABLES

• genindex

• modindex

• search

39

Page 44: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

Alembic Documentation, Release 0.1.2

40 Chapter 5. Indices and tables

Page 45: Alembic Documentation · To begin, make sure Alembic is installed as described at Installation. 2.1The Migration Environment Usage of Alembic starts with creation of the Migration

PYTHON MODULE INDEX

aalembic.command, 32alembic.config, 32alembic.context, 27alembic.ddl, 34alembic.ddl.base, 34alembic.ddl.impl, 35alembic.ddl.mssql, 36alembic.ddl.mysql, 36alembic.ddl.postgresql, 37alembic.ddl.sqlite, 37alembic.op, 19alembic.script, 34

41