Skip to content

Commit

Permalink
Do not generate a migration if no schema changes are found
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelgrinberg committed Aug 24, 2015
1 parent 4e15e53 commit 626c83f
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 10 deletions.
17 changes: 11 additions & 6 deletions flask_migrate/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import argparse
from flask import current_app
from flask.ext.script import Manager
from alembic import __version__ as __alembic_version__
Expand All @@ -17,8 +18,10 @@ def __init__(self, db, directory, **kwargs):

@property
def metadata(self):
"""Backwards compatibility, in old releases app.extensions['migrate']
was set to db, and env.py accessed app.extensions['migrate'].metadata"""
"""
Backwards compatibility, in old releases app.extensions['migrate']
was set to db, and env.py accessed app.extensions['migrate'].metadata
"""
return self.db.metadata


Expand All @@ -39,14 +42,16 @@ def get_template_directory(self):
return os.path.join(package_dir, 'templates')


def _get_config(directory, x_arg=None):
def _get_config(directory, x_arg=None, opts=None):
if directory is None:
directory = current_app.extensions['migrate'].directory
config = Config(os.path.join(directory, 'alembic.ini'))
config.set_main_option('script_location', directory)
if config.cmd_opts is None:
config.cmd_opts = argparse.Namespace()
for opt in opts or []:
setattr(config.cmd_opts, opt, True)
if x_arg is not None:
if config.cmd_opts is None:
config.cmd_opts = lambda: None
if not getattr(config.cmd_opts, 'x', None):
setattr(config.cmd_opts, 'x', [x_arg])
else:
Expand Down Expand Up @@ -143,7 +148,7 @@ def revision(directory=None, message=None, autogenerate=False, sql=False,
def migrate(directory=None, message=None, sql=False, head='head', splice=False,
branch_label=None, version_path=None, rev_id=None):
"""Alias for 'revision --autogenerate'"""
config = _get_config(directory)
config = _get_config(directory, opts=['autogenerate'])
if alembic_version >= (0, 7, 0):
command.revision(config, message, autogenerate=True, sql=sql, head=head,
splice=splice, branch_label=branch_label,
Expand Down
20 changes: 18 additions & 2 deletions flask_migrate/templates/flask-multidb/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,23 @@ def run_migrations_online():
"""

# this callback is used to prevent an auto-migration from being generated
# when there are no changes to the schema
# reference: http://alembic.readthedocs.org/en/latest/cookbook.html
def process_revision_directives(context, revision, directives):
if getattr(config.cmd_opts, 'autogenerate', False):
script = directives[0]
if len(script.upgrade_ops_list) >= len(bind_names) + 1:
empty = True
for upgrade_ops in script.upgrade_ops_list:
if not upgrade_ops.is_empty():
empty = False
if empty:
directives[:] = []
logger.info('No changes in schema detected.')

# for the direct-to-DB use case, start a transaction on all
# engines, then run all migrations, then commit all transactions.

engines = {'': {'engine': engine_from_config(
config.get_section(config.config_ini_section),
prefix='sqlalchemy.',
Expand Down Expand Up @@ -117,7 +131,9 @@ def run_migrations_online():
connection=rec['connection'],
upgrade_token="%s_upgrades" % name,
downgrade_token="%s_downgrades" % name,
target_metadata=get_metadata(name)
target_metadata=get_metadata(name),
process_revision_directives=process_revision_directives,
**current_app.extensions['migrate'].configure_args
)
context.run_migrations(engine_name=name)

Expand Down
18 changes: 16 additions & 2 deletions flask_migrate/templates/flask/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from alembic import context
from sqlalchemy import engine_from_config, pool
from logging.config import fileConfig
import logging

# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
Expand All @@ -10,13 +11,15 @@
# Interpret the config file for Python logging.
# This line sets up loggers basically.
fileConfig(config.config_file_name)
logger = logging.getLogger('alembic.env')

# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
from flask import current_app
config.set_main_option('sqlalchemy.url', current_app.config.get('SQLALCHEMY_DATABASE_URI'))
config.set_main_option('sqlalchemy.url',
current_app.config.get('SQLALCHEMY_DATABASE_URI'))
target_metadata = current_app.extensions['migrate'].db.metadata

# other values from the config, defined by the needs of env.py,
Expand Down Expand Up @@ -51,13 +54,25 @@ def run_migrations_online():
and associate a connection with the context.
"""

# this callback is used to prevent an auto-migration from being generated
# when there are no changes to the schema
# reference: http://alembic.readthedocs.org/en/latest/cookbook.html
def process_revision_directives(context, revision, directives):
if getattr(config.cmd_opts, 'autogenerate', False):
script = directives[0]
if script.upgrade_ops.is_empty():
directives[:] = []
logger.info('No changes in schema detected.')

engine = engine_from_config(config.get_section(config.config_ini_section),
prefix='sqlalchemy.',
poolclass=pool.NullPool)

connection = engine.connect()
context.configure(connection=connection,
target_metadata=target_metadata,
process_revision_directives=process_revision_directives,
**current_app.extensions['migrate'].configure_args)

try:
Expand All @@ -70,4 +85,3 @@ def run_migrations_online():
run_migrations_offline()
else:
run_migrations_online()

1 change: 1 addition & 0 deletions tests/app.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#!/bin/env python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager
Expand Down
1 change: 1 addition & 0 deletions tests/app_multidb.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#!/bin/env python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager
Expand Down

0 comments on commit 626c83f

Please sign in to comment.