Flask-Alembic¶
Flask-Alembic is a Flask extension that provides a configurable Alembic migration environment around a Flask-SQLAlchemy database.
Installation¶
Releases are available from the PyPI project page. Install with pip:
pip install Flask-Alembic
The latest code is hosted on BitBucket. Install with pip:
pip install https://bitbucket.org/davidism/flask-alembic/get/tip.zip
Configuration¶
Configuration for Alembic and its migrations is pulled from the following Flask config keys.
ALEMBIC
is a dictionary containing general configuration, mostly used byalembic.config.Config
andalembic.script.ScriptDirectory
. See Alembic’s docs on config.ALEMBIC_CONTEXT
is a dictionary containing options passed toalembic.environment.EnvironmentContext
andalembic.migration.MigrationContext
. See Alembic’s docs on context.
The only required configuration is ALEMBIC['script_location']
, which is the location of the migrations directory. If it is not an absolute path, it will be relative to the instance folder.
Basic Usage¶
First, set up your Flask app (or app factory) and the Flask-SQLAlchemy extension and models.
This extension follows the common pattern of Flask extension setup. Either immediately pass an app to Alembic
, or call init_app()
later.
from flask_alembic import Alembic
alembic = Alembic()
alembic.init_app(app) # call in the app factory if you're using that pattern
When an app is registered, mkdir()
is called to set up the migrations directory if it does not already exist. To prevent this, call init_app
with run_mkdir=False
.
The alembic
instance provides an interface between the current app and Alembic. It exposes similar commands to the command line available from Alembic, but Flask-Alembic’s methods return data rather than produce output. You can use this interface to do what the command line commands do, from inside your app.
# generate a new revision
# same as ./manage.py db revision 'made changes'
alembic.revision('made changes')
# run all available upgrades
# same as ./manage.py db upgrade
alembic.upgrade()
You can also get at the Alembic internals that enable these commands. See the Alembic API docs for more information.
alembic.script.get_revision('head') # locate a revision by name
alembic.context.get_current_revision() # could compare this to the 'head' revision above to see if upgrades are needed
alembic.op.drop_column('my_table', 'my_column') # probably don't want to do this outside a revision, but it'll work
alembic.compare_metadata() # see that that column you just dropped will be added back next revision
Command Line¶
Currently, Flask-Script and Click are supported. The commands are the same for either one.
If you have set up a flask_script.Manager
for your project using Flask-Script, you can add Alembic commands like this:
from flask_alembic.cli.script import manager as alembic_manager
app_manager.add_command('db', alembic_manager)
If you are using a newer Flask, the preferred interface is Click. If you are using Flask 0.10, you can use backported integration via Flask-CLI.
from flask_alembic.cli.click import cli as alembic_cli
app.cli.add_command(alembic_cli, 'db')
Differences from Alembic¶
- Configuration is taken from Flask instead of alembic.ini.
- The migrations are stored directly in the migrations folder instead of the versions folder.
- The extension provides the migration environment instead of env.py. If you want to change how migrations are run, subclass the extension and implement your own
run_migrations
method. - Does not (currently) support offline migrations.
API Reference¶
flask_alembic¶
-
class
flask_alembic.
Alembic
(app=None, run_mkdir=True)¶ Provide an Alembic environment and migration API.
If instantiated without an app instance,
init_app()
is used to register an app at a later time.Parameters: - app – call
init_app()
on this app - run_mkdir – whether to run
mkdir()
duringinit_app()
-
init_app
(app, run_mkdir=None)¶ Register this extension on an app. Will automatically set up migration directory by default.
Parameters: - app – app to register
- run_mkdir – whether to run
mkdir()
-
script
¶ Get the Alembic
ScriptDirectory
for the current app.
-
env
¶ Get the Alembic
EnvironmentContext
for the current app.
-
context
¶ Get the Alembic
MigrationContext
for the current app.
-
op
¶ Get the Alembic
Operations
context for the current app.
-
run_migrations
(fn, **kwargs)¶ Configure an Alembic
MigrationContext
to run migrations for the given function.This takes the place of Alembic’s env.py file, specifically the
run_migrations_online
function.Parameters: - fn – use this function to control what migrations are run
- kwargs – extra arguments passed to revision function
-
mkdir
()¶ Create the script directory and template.
-
current
()¶ Get the list of current revisions.
-
heads
(resolve_dependencies=False)¶ Get the list of revisions that have no child revisions.
Parameters: resolve_dependencies – treat dependencies as down revisions
-
branches
()¶ Get the list of revisions that have more than one next revision.
-
log
(start='base', end='heads')¶ Get the list of revisions in the order they will run.
Parameters: - start – only get since this revision
- end – only get until this revision
-
stamp
(target='heads')¶ Set the current database revision without running migrations.
Parameters: target – revision to set to, default ‘heads’
-
upgrade
(target='heads')¶ Run migrations to upgrade database.
Parameters: target – revision to go to, default ‘heads’
-
downgrade
(target=-1)¶ Run migrations to downgrade database.
Parameters: target – revision to go down to, default -1
-
revision
(message, empty=False, branch='default', parent='head', splice=False, depend=None, label=None, path=None)¶ Create a new revision. By default, auto-generate operations by comparing models and database.
Parameters: - message – description of revision
- empty – don’t auto-generate operations
- branch – use this independent branch name
- parent – parent revision(s) of this revision
- splice – allow non-head parent revision
- depend – revision(s) this revision depends on
- label – label(s) to apply to this revision
- path – where to store this revision
Returns: new revision
-
merge
(revisions='heads', message=None, label=None)¶ Create a merge revision.
Parameters: - revisions – revisions to merge
- message – description of merge, will default to revisions param
- label – label(s) to apply to this revision
Returns: new revision
-
compare_metadata
()¶ Generate a list of operations that would be present in a new revision.
- app – call
flask_alembic.cli¶
Provide integration with cli libraries.
Integration with Flask-Script:
from flask_alembic.cli.script import manager as alembic_manager
manager.add_command('db', alembic_manager)
Base functions that write information to the terminal.
-
flask_alembic.cli.base.
mkdir
()¶ Create the migration directory if it does not exist.
-
flask_alembic.cli.base.
current
(verbose=False)¶ Show the list of current revisions.
-
flask_alembic.cli.base.
heads
(resolve_dependencies=False, verbose=False)¶ Show the list of revisions that have no child revisions.
-
flask_alembic.cli.base.
branches
(verbose=False)¶ Show the list of revisions that have more than one next revision.
-
flask_alembic.cli.base.
log
(start='base', end='heads', verbose=False)¶ Show the list of revisions in the order they will run.
-
flask_alembic.cli.base.
show
(revisions)¶ Show the given revisions.
-
flask_alembic.cli.base.
stamp
(target='heads')¶ Set the current revision without running migrations.
-
flask_alembic.cli.base.
upgrade
(target='heads')¶ Run migrations to upgrade the database.
-
flask_alembic.cli.base.
downgrade
(target=-1)¶ Run migration to downgrade the database.
-
flask_alembic.cli.base.
revision
(message, empty=False, branch='default', parent='head', splice=False, depend=None, label=None, path=None)¶ Generate a new revision.
-
flask_alembic.cli.base.
merge
(revisions, message=None, label=None)¶ Generate a merge revision.