Skip to content

Commit

Permalink
Pass custom Alembic configuration options, such as compare_type.
Browse files Browse the repository at this point in the history
Also the tests have been restructured for clarity.
  • Loading branch information
miguelgrinberg committed Apr 26, 2015
1 parent e40dd4c commit ee32ae4
Show file tree
Hide file tree
Showing 10 changed files with 108 additions and 58 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ python:
- 2.6
- 2.7
- 3.3
- 3.4
- pypy
install: python setup.py install
script: python setup.py test
3 changes: 2 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ Flask-Migrate exposes two objects, ``Migrate`` and ``MigrateCommand``. The forme
migrate = Migrate(app, db)
manager.add_command('db', MigrateCommand)

The two arguments to ``Migrate`` are the application instance and the Flask-SQLAlchemy database instance.
The two arguments to ``Migrate`` are the application instance and the Flask-SQLAlchemy database instance. The ``Migrate`` constructor also takes additional keyword arguments, which are passed to Alembic's ``EnvironmentContext.configure()`` method.


The application will now have a ``db`` command line option with several sub-commands. If your launch script is called ``manage.py`` then the commands are:

Expand Down
11 changes: 6 additions & 5 deletions flask_migrate/__init__.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@


class _MigrateConfig(object):
def __init__(self, db, directory):
def __init__(self, db, directory, **kwargs):
self.db = db
self.directory = directory
self.configure_args = kwargs

@property
def metadata(self):
Expand All @@ -22,14 +23,14 @@ def metadata(self):


class Migrate(object):
def __init__(self, app=None, db=None, directory='migrations'):
def __init__(self, app=None, db=None, directory='migrations', **kwargs):
if app is not None and db is not None:
self.init_app(app, db, directory)
self.init_app(app, db, directory, **kwargs)

def init_app(self, app, db, directory='migrations'):
def init_app(self, app, db, directory='migrations', **kwargs):
if not hasattr(app, 'extensions'):
app.extensions = {}
app.extensions['migrate'] = _MigrateConfig(db, directory)
app.extensions['migrate'] = _MigrateConfig(db, directory, **kwargs)


class Config(AlembicConfig):
Expand Down
16 changes: 8 additions & 8 deletions flask_migrate/templates/flask/env.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
# my_important_option = config.get_main_option("my_important_option")
# ... etc.


def run_migrations_offline():
"""Run migrations in 'offline' mode.
Expand All @@ -42,23 +43,22 @@ def run_migrations_offline():
with context.begin_transaction():
context.run_migrations()


def run_migrations_online():
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
engine = engine_from_config(
config.get_section(config.config_ini_section),
prefix='sqlalchemy.',
poolclass=pool.NullPool)
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
)
context.configure(connection=connection,
target_metadata=target_metadata,
**current_app.extensions['migrate'].configure_args)

try:
with context.begin_transaction():
Expand Down
Empty file modified tests/app.py
100644 → 100755
Empty file.
21 changes: 21 additions & 0 deletions tests/app_compare_type1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'

db = SQLAlchemy(app)
migrate = Migrate(app, db, compare_type=True)

manager = Manager(app)
manager.add_command('db', MigrateCommand)


class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(128))

if __name__ == '__main__':
manager.run()
21 changes: 21 additions & 0 deletions tests/app_compare_type2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'

db = SQLAlchemy(app)
migrate = Migrate(app, db, compare_type=True)

manager = Manager(app)
manager.add_command('db', MigrateCommand)


class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(10))

if __name__ == '__main__':
manager.run()
2 changes: 1 addition & 1 deletion tests/app2.py → tests/app_custom_directory.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from flask_migrate import Migrate, MigrateCommand

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app2.db'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'

db = SQLAlchemy(app)
migrate = Migrate(app, db, directory='temp_folder/temp_migrations')
Expand Down
52 changes: 48 additions & 4 deletions tests/test_migrate.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import os
import shutil
import unittest
import subprocess
import shlex


def run_cmd(cmd):
"""Run a command and return a tuple with (stdout, stderr, exit_code)"""
process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(stdout, stderr) = process.communicate()
return stdout, stderr, process.wait()


class TestMigrate(unittest.TestCase):
Expand All @@ -14,10 +24,10 @@ def setUp(self):
shutil.rmtree('migrations')
except OSError:
pass

os.system('python app.py db init')
os.system('python app.py db migrate')
os.system('python app.py db upgrade')
try:
shutil.rmtree('temp_folder')
except OSError:
pass

def tearDown(self):
try:
Expand All @@ -28,6 +38,10 @@ def tearDown(self):
shutil.rmtree('migrations')
except OSError:
pass
try:
shutil.rmtree('temp_folder')
except OSError:
pass

def test_alembic_version(self):
from flask_migrate import alembic_version
Expand All @@ -36,10 +50,40 @@ def test_alembic_version(self):
self.assertTrue(isinstance(v, int))

def test_migrate_upgrade(self):
(o, e, s) = run_cmd('python app.py db init')
self.assertTrue(s == 0)
(o, e, s) = run_cmd('python app.py db migrate')
self.assertTrue(s == 0)
(o, e, s) = run_cmd('python app.py db upgrade')
self.assertTrue(s == 0)

from .app import db, User
db.session.add(User(name='test'))
db.session.commit()

def test_custom_directory(self):
(o, e, s) = run_cmd('python app_custom_directory.py db init')
self.assertTrue(s == 0)
(o, e, s) = run_cmd('python app_custom_directory.py db migrate')
self.assertTrue(s == 0)
(o, e, s) = run_cmd('python app_custom_directory.py db upgrade')
self.assertTrue(s == 0)

from .app_custom_directory import db, User
db.session.add(User(name='test'))
db.session.commit()

def test_compare_type(self):
(o, e, s) = run_cmd('python app_compare_type1.py db init')
self.assertTrue(s == 0)
(o, e, s) = run_cmd('python app_compare_type1.py db migrate')
self.assertTrue(s == 0)
(o, e, s) = run_cmd('python app_compare_type1.py db upgrade')
self.assertTrue(s == 0)
(o, e, s) = run_cmd('python app_compare_type2.py db migrate')
self.assertTrue(s == 0)
self.assertTrue(b'Detected type change from VARCHAR(length=128) '
b'to String(length=10)' in e)

if __name__ == '__main__':
unittest.main()
39 changes: 0 additions & 39 deletions tests/test_migrate_custom_directory.py

This file was deleted.

0 comments on commit ee32ae4

Please sign in to comment.