Flask-Migrate-2.1.1/0000755€´ä€_›j0000000000013151112065014456 5ustar migu778100000000000000Flask-Migrate-2.1.1/flask_migrate/0000755€´ä€_›j0000000000013151112065017266 5ustar migu778100000000000000Flask-Migrate-2.1.1/flask_migrate/__init__.py0000755€´ä€_›j0000004372613151111616021417 0ustar migu778100000000000000import os import argparse from flask import current_app try: from flask_script import Manager except ImportError: Manager = None from alembic import __version__ as __alembic_version__ from alembic.config import Config as AlembicConfig from alembic import command alembic_version = tuple([int(v) for v in __alembic_version__.split('.')[0:3]]) class _MigrateConfig(object): def __init__(self, migrate, db, **kwargs): self.migrate = migrate self.db = db self.directory = migrate.directory self.configure_args = 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 """ return self.db.metadata class Config(AlembicConfig): def get_template_directory(self): package_dir = os.path.abspath(os.path.dirname(__file__)) return os.path.join(package_dir, 'templates') class Migrate(object): def __init__(self, app=None, db=None, directory='migrations', **kwargs): self.configure_callbacks = [] self.db = db self.directory = directory self.alembic_ctx_kwargs = kwargs if app is not None and db is not None: self.init_app(app, db, directory) def init_app(self, app, db=None, directory=None, **kwargs): self.db = db or self.db self.directory = directory or self.directory self.alembic_ctx_kwargs.update(kwargs) if not hasattr(app, 'extensions'): app.extensions = {} app.extensions['migrate'] = _MigrateConfig(self, self.db, **self.alembic_ctx_kwargs) def configure(self, f): self.configure_callbacks.append(f) return f def call_configure_callbacks(self, config): for f in self.configure_callbacks: config = f(config) return config def get_config(self, directory=None, x_arg=None, opts=None): if directory is None: directory = self.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 not hasattr(config.cmd_opts, 'x'): if x_arg is not None: setattr(config.cmd_opts, 'x', []) if isinstance(x_arg, list) or isinstance(x_arg, tuple): for x in x_arg: config.cmd_opts.x.append(x) else: config.cmd_opts.x.append(x_arg) else: setattr(config.cmd_opts, 'x', None) return self.call_configure_callbacks(config) if Manager is not None: MigrateCommand = Manager(usage='Perform database migrations') else: class FakeCommand(object): def option(self, *args, **kwargs): def decorator(f): return f return decorator MigrateCommand = FakeCommand() @MigrateCommand.option('-d', '--directory', dest='directory', default=None, help=("migration script directory (default is " "'migrations')")) @MigrateCommand.option('--multidb', dest='multidb', action='store_true', default=False, help=("Multiple databases migraton (default is " "False)")) def init(directory=None, multidb=False): """Creates a new migration repository""" if directory is None: directory = current_app.extensions['migrate'].directory config = Config() config.set_main_option('script_location', directory) config.config_file_name = os.path.join(directory, 'alembic.ini') config = current_app.extensions['migrate'].\ migrate.call_configure_callbacks(config) if multidb: command.init(config, directory, 'flask-multidb') else: command.init(config, directory, 'flask') @MigrateCommand.option('--rev-id', dest='rev_id', default=None, help=('Specify a hardcoded revision id instead of ' 'generating one')) @MigrateCommand.option('--version-path', dest='version_path', default=None, help=('Specify specific path from config for version ' 'file')) @MigrateCommand.option('--branch-label', dest='branch_label', default=None, help=('Specify a branch label to apply to the new ' 'revision')) @MigrateCommand.option('--splice', dest='splice', action='store_true', default=False, help=('Allow a non-head revision as the "head" to ' 'splice onto')) @MigrateCommand.option('--head', dest='head', default='head', help=('Specify head revision or @head to ' 'base new revision on')) @MigrateCommand.option('--sql', dest='sql', action='store_true', default=False, help=("Don't emit SQL to database - dump to standard " "output instead")) @MigrateCommand.option('--autogenerate', dest='autogenerate', action='store_true', default=False, help=('Populate revision script with candidate ' 'migration operations, based on comparison of ' 'database to model')) @MigrateCommand.option('-m', '--message', dest='message', default=None, help='Revision message') @MigrateCommand.option('-d', '--directory', dest='directory', default=None, help=("migration script directory (default is " "'migrations')")) def revision(directory=None, message=None, autogenerate=False, sql=False, head='head', splice=False, branch_label=None, version_path=None, rev_id=None): """Create a new revision file.""" config = current_app.extensions['migrate'].migrate.get_config(directory) if alembic_version >= (0, 7, 0): command.revision(config, message, autogenerate=autogenerate, sql=sql, head=head, splice=splice, branch_label=branch_label, version_path=version_path, rev_id=rev_id) else: command.revision(config, message, autogenerate=autogenerate, sql=sql) @MigrateCommand.option('--rev-id', dest='rev_id', default=None, help=('Specify a hardcoded revision id instead of ' 'generating one')) @MigrateCommand.option('--version-path', dest='version_path', default=None, help=('Specify specific path from config for version ' 'file')) @MigrateCommand.option('--branch-label', dest='branch_label', default=None, help=('Specify a branch label to apply to the new ' 'revision')) @MigrateCommand.option('--splice', dest='splice', action='store_true', default=False, help=('Allow a non-head revision as the "head" to ' 'splice onto')) @MigrateCommand.option('--head', dest='head', default='head', help=('Specify head revision or @head to ' 'base new revision on')) @MigrateCommand.option('--sql', dest='sql', action='store_true', default=False, help=("Don't emit SQL to database - dump to standard " "output instead")) @MigrateCommand.option('-m', '--message', dest='message', default=None) @MigrateCommand.option('-d', '--directory', dest='directory', default=None, help=("migration script directory (default is " "'migrations')")) @MigrateCommand.option('-x', '--x-arg', dest='x_arg', default=None, action='append', help=("Additional arguments consumed " "by custom env.py scripts")) def migrate(directory=None, message=None, sql=False, head='head', splice=False, branch_label=None, version_path=None, rev_id=None, x_arg=None): """Alias for 'revision --autogenerate'""" config = current_app.extensions['migrate'].migrate.get_config( directory, opts=['autogenerate'], x_arg=x_arg) if alembic_version >= (0, 7, 0): command.revision(config, message, autogenerate=True, sql=sql, head=head, splice=splice, branch_label=branch_label, version_path=version_path, rev_id=rev_id) else: command.revision(config, message, autogenerate=True, sql=sql) @MigrateCommand.option('revision', nargs='?', default='head', help="revision identifier") @MigrateCommand.option('-d', '--directory', dest='directory', default=None, help=("migration script directory (default is " "'migrations')")) def edit(directory=None, revision='current'): """Edit current revision.""" if alembic_version >= (0, 8, 0): config = current_app.extensions['migrate'].migrate.get_config( directory) command.edit(config, revision) else: raise RuntimeError('Alembic 0.8.0 or greater is required') @MigrateCommand.option('--rev-id', dest='rev_id', default=None, help=('Specify a hardcoded revision id instead of ' 'generating one')) @MigrateCommand.option('--branch-label', dest='branch_label', default=None, help=('Specify a branch label to apply to the new ' 'revision')) @MigrateCommand.option('-m', '--message', dest='message', default=None) @MigrateCommand.option('revisions', nargs='+', help='one or more revisions, or "heads" for all heads') @MigrateCommand.option('-d', '--directory', dest='directory', default=None, help=("migration script directory (default is " "'migrations')")) def merge(directory=None, revisions='', message=None, branch_label=None, rev_id=None): """Merge two revisions together. Creates a new migration file""" if alembic_version >= (0, 7, 0): config = current_app.extensions['migrate'].migrate.get_config( directory) command.merge(config, revisions, message=message, branch_label=branch_label, rev_id=rev_id) else: raise RuntimeError('Alembic 0.7.0 or greater is required') @MigrateCommand.option('--tag', dest='tag', default=None, help=("Arbitrary 'tag' name - can be used by custom " "env.py scripts")) @MigrateCommand.option('--sql', dest='sql', action='store_true', default=False, help=("Don't emit SQL to database - dump to standard " "output instead")) @MigrateCommand.option('revision', nargs='?', default='head', help="revision identifier") @MigrateCommand.option('-d', '--directory', dest='directory', default=None, help=("migration script directory (default is " "'migrations')")) @MigrateCommand.option('-x', '--x-arg', dest='x_arg', default=None, action='append', help=("Additional arguments consumed " "by custom env.py scripts")) def upgrade(directory=None, revision='head', sql=False, tag=None, x_arg=None): """Upgrade to a later version""" config = current_app.extensions['migrate'].migrate.get_config(directory, x_arg=x_arg) command.upgrade(config, revision, sql=sql, tag=tag) @MigrateCommand.option('--tag', dest='tag', default=None, help=("Arbitrary 'tag' name - can be used by custom " "env.py scripts")) @MigrateCommand.option('--sql', dest='sql', action='store_true', default=False, help=("Don't emit SQL to database - dump to standard " "output instead")) @MigrateCommand.option('revision', nargs='?', default="-1", help="revision identifier") @MigrateCommand.option('-d', '--directory', dest='directory', default=None, help=("migration script directory (default is " "'migrations')")) @MigrateCommand.option('-x', '--x-arg', dest='x_arg', default=None, action='append', help=("Additional arguments consumed " "by custom env.py scripts")) def downgrade(directory=None, revision='-1', sql=False, tag=None, x_arg=None): """Revert to a previous version""" config = current_app.extensions['migrate'].migrate.get_config(directory, x_arg=x_arg) if sql and revision == '-1': revision = 'head:-1' command.downgrade(config, revision, sql=sql, tag=tag) @MigrateCommand.option('revision', nargs='?', default="head", help="revision identifier") @MigrateCommand.option('-d', '--directory', dest='directory', default=None, help=("migration script directory (default is " "'migrations')")) def show(directory=None, revision='head'): """Show the revision denoted by the given symbol.""" if alembic_version >= (0, 7, 0): config = current_app.extensions['migrate'].migrate.get_config( directory) command.show(config, revision) else: raise RuntimeError('Alembic 0.7.0 or greater is required') @MigrateCommand.option('-v', '--verbose', dest='verbose', action='store_true', default=False, help='Use more verbose output') @MigrateCommand.option('-r', '--rev-range', dest='rev_range', default=None, help='Specify a revision range; format is [start]:[end]') @MigrateCommand.option('-d', '--directory', dest='directory', default=None, help=("migration script directory (default is " "'migrations')")) def history(directory=None, rev_range=None, verbose=False): """List changeset scripts in chronological order.""" config = current_app.extensions['migrate'].migrate.get_config(directory) if alembic_version >= (0, 7, 0): command.history(config, rev_range, verbose=verbose) else: command.history(config, rev_range) @MigrateCommand.option('--resolve-dependencies', dest='resolve_dependencies', action='store_true', default=False, help='Treat dependency versions as down revisions') @MigrateCommand.option('-v', '--verbose', dest='verbose', action='store_true', default=False, help='Use more verbose output') @MigrateCommand.option('-d', '--directory', dest='directory', default=None, help=("migration script directory (default is " "'migrations')")) def heads(directory=None, verbose=False, resolve_dependencies=False): """Show current available heads in the script directory""" if alembic_version >= (0, 7, 0): config = current_app.extensions['migrate'].migrate.get_config( directory) command.heads(config, verbose=verbose, resolve_dependencies=resolve_dependencies) else: raise RuntimeError('Alembic 0.7.0 or greater is required') @MigrateCommand.option('-v', '--verbose', dest='verbose', action='store_true', default=False, help='Use more verbose output') @MigrateCommand.option('-d', '--directory', dest='directory', default=None, help=("migration script directory (default is " "'migrations')")) def branches(directory=None, verbose=False): """Show current branch points""" config = current_app.extensions['migrate'].migrate.get_config(directory) if alembic_version >= (0, 7, 0): command.branches(config, verbose=verbose) else: command.branches(config) @MigrateCommand.option('--head-only', dest='head_only', action='store_true', default=False, help='Deprecated. Use --verbose for additional output') @MigrateCommand.option('-v', '--verbose', dest='verbose', action='store_true', default=False, help='Use more verbose output') @MigrateCommand.option('-d', '--directory', dest='directory', default=None, help=("migration script directory (default is " "'migrations')")) def current(directory=None, verbose=False, head_only=False): """Display the current revision for each database.""" config = current_app.extensions['migrate'].migrate.get_config(directory) if alembic_version >= (0, 7, 0): command.current(config, verbose=verbose, head_only=head_only) else: command.current(config) @MigrateCommand.option('--tag', dest='tag', default=None, help=("Arbitrary 'tag' name - can be used by custom " "env.py scripts")) @MigrateCommand.option('--sql', dest='sql', action='store_true', default=False, help=("Don't emit SQL to database - dump to standard " "output instead")) @MigrateCommand.option('revision', default=None, help="revision identifier") @MigrateCommand.option('-d', '--directory', dest='directory', default=None, help=("migration script directory (default is " "'migrations')")) def stamp(directory=None, revision='head', sql=False, tag=None): """'stamp' the revision table with the given revision; don't run any migrations""" config = current_app.extensions['migrate'].migrate.get_config(directory) command.stamp(config, revision, sql=sql, tag=tag) Flask-Migrate-2.1.1/flask_migrate/cli.py0000644€´ä€_›j0000002233213113417235020416 0ustar migu778100000000000000import click from flask.cli import with_appcontext from flask_migrate import init as _init from flask_migrate import revision as _revision from flask_migrate import migrate as _migrate from flask_migrate import edit as _edit from flask_migrate import merge as _merge from flask_migrate import upgrade as _upgrade from flask_migrate import downgrade as _downgrade from flask_migrate import show as _show from flask_migrate import history as _history from flask_migrate import heads as _heads from flask_migrate import branches as _branches from flask_migrate import current as _current from flask_migrate import stamp as _stamp @click.group() def db(): """Perform database migrations.""" pass @db.command() @click.option('-d', '--directory', default=None, help=('migration script directory (default is "migrations")')) @click.option('--multidb', is_flag=True, help=('Support multiple databases')) @with_appcontext def init(directory, multidb): """Creates a new migration repository.""" _init(directory, multidb) @db.command() @click.option('-d', '--directory', default=None, help=('migration script directory (default is "migrations")')) @click.option('-m', '--message', default=None, help='Revision message') @click.option('--autogenerate', is_flag=True, help=('Populate revision script with candidate migration ' 'operations, based on comparison of database to model')) @click.option('--sql', is_flag=True, help=('Don\'t emit SQL to database - dump to standard output ' 'instead')) @click.option('--head', default='head', help=('Specify head revision or @head to base new ' 'revision on')) @click.option('--splice', is_flag=True, help=('Allow a non-head revision as the "head" to splice onto')) @click.option('--branch-label', default=None, help=('Specify a branch label to apply to the new revision')) @click.option('--version-path', default=None, help=('Specify specific path from config for version file')) @click.option('--rev-id', default=None, help=('Specify a hardcoded revision id instead of generating ' 'one')) @with_appcontext def revision(directory, message, autogenerate, sql, head, splice, branch_label, version_path, rev_id): """Create a new revision file.""" _revision(directory, message, autogenerate, sql, head, splice, branch_label, version_path, rev_id) @db.command() @click.option('-d', '--directory', default=None, help=('migration script directory (default is "migrations")')) @click.option('-m', '--message', default=None, help='Revision message') @click.option('--sql', is_flag=True, help=('Don\'t emit SQL to database - dump to standard output ' 'instead')) @click.option('--head', default='head', help=('Specify head revision or @head to base new ' 'revision on')) @click.option('--splice', is_flag=True, help=('Allow a non-head revision as the "head" to splice onto')) @click.option('--branch-label', default=None, help=('Specify a branch label to apply to the new revision')) @click.option('--version-path', default=None, help=('Specify specific path from config for version file')) @click.option('--rev-id', default=None, help=('Specify a hardcoded revision id instead of generating ' 'one')) @click.option('-x', '--x-arg', multiple=True, help='Additional arguments consumed by custom env.py scripts') @with_appcontext def migrate(directory, message, sql, head, splice, branch_label, version_path, rev_id, x_arg): """Autogenerate a new revision file (Alias for 'revision --autogenerate')""" _migrate(directory, message, sql, head, splice, branch_label, version_path, rev_id, x_arg) @db.command() @click.option('-d', '--directory', default=None, help=('migration script directory (default is "migrations")')) @click.argument('revision', default='head') @with_appcontext def edit(directory, revision): """Edit a revision file""" _edit(directory, revision) @db.command() @click.option('-d', '--directory', default=None, help=('migration script directory (default is "migrations")')) @click.option('-m', '--message', default=None, help='Merge revision message') @click.option('--branch-label', default=None, help=('Specify a branch label to apply to the new revision')) @click.option('--rev-id', default=None, help=('Specify a hardcoded revision id instead of generating ' 'one')) @click.argument('revisions', nargs=-1) @with_appcontext def merge(directory, message, branch_label, rev_id, revisions): """Merge two revisions together, creating a new revision file""" _merge(directory, revisions, message, branch_label, rev_id) @db.command() @click.option('-d', '--directory', default=None, help=('migration script directory (default is "migrations")')) @click.option('--sql', is_flag=True, help=('Don\'t emit SQL to database - dump to standard output ' 'instead')) @click.option('--tag', default=None, help=('Arbitrary "tag" name - can be used by custom "env.py ' 'scripts')) @click.option('-x', '--x-arg', multiple=True, help='Additional arguments consumed by custom env.py scripts') @click.argument('revision', default='head') @with_appcontext def upgrade(directory, sql, tag, x_arg, revision): """Upgrade to a later version""" _upgrade(directory, revision, sql, tag, x_arg) @db.command() @click.option('-d', '--directory', default=None, help=('migration script directory (default is "migrations")')) @click.option('--sql', is_flag=True, help=('Don\'t emit SQL to database - dump to standard output ' 'instead')) @click.option('--tag', default=None, help=('Arbitrary "tag" name - can be used by custom "env.py ' 'scripts')) @click.option('-x', '--x-arg', multiple=True, help='Additional arguments consumed by custom env.py scripts') @click.argument('revision', default='-1') @with_appcontext def downgrade(directory, sql, tag, x_arg, revision): """Revert to a previous version""" _downgrade(directory, revision, sql, tag, x_arg) @db.command() @click.option('-d', '--directory', default=None, help=('migration script directory (default is "migrations")')) @click.argument('revision', default='head') @with_appcontext def show(directory, revision): """Show the revision denoted by the given symbol.""" _show(directory, revision) @db.command() @click.option('-d', '--directory', default=None, help=('migration script directory (default is "migrations")')) @click.option('-r', '--rev-range', default=None, help='Specify a revision range; format is [start]:[end]') @click.option('-v', '--verbose', is_flag=True, help='Use more verbose output') @with_appcontext def history(directory, rev_range, verbose): """List changeset scripts in chronological order.""" _history(directory, rev_range, verbose) @db.command() @click.option('-d', '--directory', default=None, help=('migration script directory (default is "migrations")')) @click.option('-v', '--verbose', is_flag=True, help='Use more verbose output') @click.option('--resolve-dependencies', is_flag=True, help='Treat dependency versions as down revisions') @with_appcontext def heads(directory, verbose, resolve_dependencies): """Show current available heads in the script directory""" _heads(directory, verbose, resolve_dependencies) @db.command() @click.option('-d', '--directory', default=None, help=('migration script directory (default is "migrations")')) @click.option('-v', '--verbose', is_flag=True, help='Use more verbose output') @with_appcontext def branches(directory, verbose): """Show current branch points""" _branches(directory, verbose) @db.command() @click.option('-d', '--directory', default=None, help=('migration script directory (default is "migrations")')) @click.option('-v', '--verbose', is_flag=True, help='Use more verbose output') @click.option('--head-only', is_flag=True, help='Deprecated. Use --verbose for additional output') @with_appcontext def current(directory, verbose, head_only): """Display the current revision for each database.""" _current(directory, verbose, head_only) @db.command() @click.option('-d', '--directory', default=None, help=('migration script directory (default is "migrations")')) @click.option('--sql', is_flag=True, help=('Don\'t emit SQL to database - dump to standard output ' 'instead')) @click.option('--tag', default=None, help=('Arbitrary "tag" name - can be used by custom "env.py ' 'scripts')) @click.argument('revision', default='head') @with_appcontext def stamp(directory, sql, tag, revision): """'stamp' the revision table with the given revision; don't run any migrations""" _stamp(directory, revision, sql, tag) Flask-Migrate-2.1.1/flask_migrate/templates/0000755€´ä€_›j0000000000013151112065021264 5ustar migu778100000000000000Flask-Migrate-2.1.1/flask_migrate/templates/flask/0000755€´ä€_›j0000000000013151112065022364 5ustar migu778100000000000000Flask-Migrate-2.1.1/flask_migrate/templates/flask/alembic.ini.mako0000644€´ä€_›j0000000140213022575400025407 0ustar migu778100000000000000# A generic, single database configuration. [alembic] # template used to generate migration files # file_template = %%(rev)s_%%(slug)s # set to 'true' to run the environment during # the 'revision' command, regardless of autogenerate # revision_environment = false # Logging configuration [loggers] keys = root,sqlalchemy,alembic [handlers] keys = console [formatters] keys = generic [logger_root] level = WARN handlers = console qualname = [logger_sqlalchemy] level = WARN handlers = qualname = sqlalchemy.engine [logger_alembic] level = INFO handlers = qualname = alembic [handler_console] class = StreamHandler args = (sys.stderr,) level = NOTSET formatter = generic [formatter_generic] format = %(levelname)-5.5s [%(name)s] %(message)s datefmt = %H:%M:%S Flask-Migrate-2.1.1/flask_migrate/templates/flask/env.py0000755€´ä€_›j0000000550413100472657023547 0ustar migu778100000000000000from __future__ import with_statement 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. config = context.config # 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')) target_metadata = current_app.extensions['migrate'].db.metadata # other values from the config, defined by the needs of env.py, # can be acquired: # my_important_option = config.get_main_option("my_important_option") # ... etc. def run_migrations_offline(): """Run migrations in 'offline' mode. This configures the context with just a URL and not an Engine, though an Engine is acceptable here as well. By skipping the Engine creation we don't even need a DBAPI to be available. Calls to context.execute() here emit the given string to the script output. """ url = config.get_main_option("sqlalchemy.url") context.configure(url=url) 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. """ # this callback is used to prevent an auto-migration from being generated # when there are no changes to the schema # reference: http://alembic.zzzcomputing.com/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: with context.begin_transaction(): context.run_migrations() finally: connection.close() if context.is_offline_mode(): run_migrations_offline() else: run_migrations_online() Flask-Migrate-2.1.1/flask_migrate/templates/flask/README0000755€´ä€_›j0000000004613022575400023252 0ustar migu778100000000000000Generic single-database configuration.Flask-Migrate-2.1.1/flask_migrate/templates/flask/script.py.mako0000755€´ä€_›j0000000075613022575400025206 0ustar migu778100000000000000"""${message} Revision ID: ${up_revision} Revises: ${down_revision | comma,n} Create Date: ${create_date} """ from alembic import op import sqlalchemy as sa ${imports if imports else ""} # revision identifiers, used by Alembic. revision = ${repr(up_revision)} down_revision = ${repr(down_revision)} branch_labels = ${repr(branch_labels)} depends_on = ${repr(depends_on)} def upgrade(): ${upgrades if upgrades else "pass"} def downgrade(): ${downgrades if downgrades else "pass"} Flask-Migrate-2.1.1/flask_migrate/templates/flask-multidb/0000755€´ä€_›j0000000000013151112065024022 5ustar migu778100000000000000Flask-Migrate-2.1.1/flask_migrate/templates/flask-multidb/alembic.ini.mako0000644€´ä€_›j0000000140213022575400027045 0ustar migu778100000000000000# A generic, single database configuration. [alembic] # template used to generate migration files # file_template = %%(rev)s_%%(slug)s # set to 'true' to run the environment during # the 'revision' command, regardless of autogenerate # revision_environment = false # Logging configuration [loggers] keys = root,sqlalchemy,alembic [handlers] keys = console [formatters] keys = generic [logger_root] level = WARN handlers = console qualname = [logger_sqlalchemy] level = WARN handlers = qualname = sqlalchemy.engine [logger_alembic] level = INFO handlers = qualname = alembic [handler_console] class = StreamHandler args = (sys.stderr,) level = NOTSET formatter = generic [formatter_generic] format = %(levelname)-5.5s [%(name)s] %(message)s datefmt = %H:%M:%S Flask-Migrate-2.1.1/flask_migrate/templates/flask-multidb/env.py0000755€´ä€_›j0000001251113100472657025201 0ustar migu778100000000000000from __future__ import with_statement from alembic import context from sqlalchemy import engine_from_config, pool, MetaData from logging.config import fileConfig import logging USE_TWOPHASE = False # this is the Alembic Config object, which provides # access to the values within the .ini file in use. config = context.config # 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')) bind_names = [] for name, url in current_app.config.get("SQLALCHEMY_BINDS").items(): context.config.set_section_option(name, "sqlalchemy.url", url) bind_names.append(name) target_metadata = current_app.extensions['migrate'].db.metadata # other values from the config, defined by the needs of env.py, # can be acquired: # my_important_option = config.get_main_option("my_important_option") # ... etc. def get_metadata(bind): """Return the metadata for a bind.""" if bind == '': bind = None m = MetaData() for t in target_metadata.tables.values(): if t.info.get('bind_key') == bind: t.tometadata(m) return m def run_migrations_offline(): """Run migrations in 'offline' mode. This configures the context with just a URL and not an Engine, though an Engine is acceptable here as well. By skipping the Engine creation we don't even need a DBAPI to be available. Calls to context.execute() here emit the given string to the script output. """ # for the --sql use case, run migrations for each URL into # individual files. engines = {'': {'url': context.config.get_main_option('sqlalchemy.url')}} for name in bind_names: engines[name] = rec = {} rec['url'] = context.config.get_section_option(name, "sqlalchemy.url") for name, rec in engines.items(): logger.info("Migrating database %s" % (name or '')) file_ = "%s.sql" % name logger.info("Writing output to %s" % file_) with open(file_, 'w') as buffer: context.configure(url=rec['url'], output_buffer=buffer, target_metadata=get_metadata(name), literal_binds=True) with context.begin_transaction(): context.run_migrations(engine_name=name) 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. """ # this callback is used to prevent an auto-migration from being generated # when there are no changes to the schema # reference: http://alembic.zzzcomputing.com/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.', poolclass=pool.NullPool)}} for name in bind_names: engines[name] = rec = {} rec['engine'] = engine_from_config( context.config.get_section(name), prefix='sqlalchemy.', poolclass=pool.NullPool) for name, rec in engines.items(): engine = rec['engine'] rec['connection'] = conn = engine.connect() if USE_TWOPHASE: rec['transaction'] = conn.begin_twophase() else: rec['transaction'] = conn.begin() try: for name, rec in engines.items(): logger.info("Migrating database %s" % (name or '')) context.configure( connection=rec['connection'], upgrade_token="%s_upgrades" % name, downgrade_token="%s_downgrades" % name, target_metadata=get_metadata(name), process_revision_directives=process_revision_directives, **current_app.extensions['migrate'].configure_args ) context.run_migrations(engine_name=name) if USE_TWOPHASE: for rec in engines.values(): rec['transaction'].prepare() for rec in engines.values(): rec['transaction'].commit() except: for rec in engines.values(): rec['transaction'].rollback() raise finally: for rec in engines.values(): rec['connection'].close() if context.is_offline_mode(): run_migrations_offline() else: run_migrations_online() Flask-Migrate-2.1.1/flask_migrate/templates/flask-multidb/README0000755€´ä€_›j0000000004613022575400024710 0ustar migu778100000000000000Generic single-database configuration.Flask-Migrate-2.1.1/flask_migrate/templates/flask-multidb/script.py.mako0000755€´ä€_›j0000000170513022575400026637 0ustar migu778100000000000000<%! import re %>"""${message} Revision ID: ${up_revision} Revises: ${down_revision | comma,n} Create Date: ${create_date} """ from alembic import op import sqlalchemy as sa ${imports if imports else ""} # revision identifiers, used by Alembic. revision = ${repr(up_revision)} down_revision = ${repr(down_revision)} branch_labels = ${repr(branch_labels)} depends_on = ${repr(depends_on)} def upgrade(engine_name): globals()["upgrade_%s" % engine_name]() def downgrade(engine_name): globals()["downgrade_%s" % engine_name]() <% from flask import current_app db_names = [''] + list(current_app.config.get("SQLALCHEMY_BINDS").keys()) %> ## generate an "upgrade_() / downgrade_()" function ## for each database name in the ini file. % for db_name in db_names: def upgrade_${db_name}(): ${context.get("%s_upgrades" % db_name, "pass")} def downgrade_${db_name}(): ${context.get("%s_downgrades" % db_name, "pass")} % endfor Flask-Migrate-2.1.1/Flask_Migrate.egg-info/0000755€´ä€_›j0000000000013151112065020660 5ustar migu778100000000000000Flask-Migrate-2.1.1/Flask_Migrate.egg-info/dependency_links.txt0000644€´ä€_›j0000000000113151112065024726 0ustar migu778100000000000000 Flask-Migrate-2.1.1/Flask_Migrate.egg-info/entry_points.txt0000644€´ä€_›j0000000005413151112065024155 0ustar migu778100000000000000[flask.commands] db = flask_migrate.cli:db Flask-Migrate-2.1.1/Flask_Migrate.egg-info/not-zip-safe0000644€´ä€_›j0000000000113022575637023125 0ustar migu778100000000000000 Flask-Migrate-2.1.1/Flask_Migrate.egg-info/PKG-INFO0000644€´ä€_›j0000000160113151112065021753 0ustar migu778100000000000000Metadata-Version: 1.1 Name: Flask-Migrate Version: 2.1.1 Summary: SQLAlchemy database migrations for Flask applications using Alembic Home-page: http://github.com/miguelgrinberg/flask-migrate/ Author: Miguel Grinberg Author-email: miguelgrinberg50@gmail.com License: MIT Description: Flask-Migrate -------------- SQLAlchemy database migrations for Flask applications using Alembic. Platform: any Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 3 Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Classifier: Topic :: Software Development :: Libraries :: Python Modules Flask-Migrate-2.1.1/Flask_Migrate.egg-info/requires.txt0000644€´ä€_›j0000000005613151112065023261 0ustar migu778100000000000000Flask>=0.9 Flask-SQLAlchemy>=1.0 alembic>=0.6 Flask-Migrate-2.1.1/Flask_Migrate.egg-info/SOURCES.txt0000644€´ä€_›j0000000241313151112065022544 0ustar migu778100000000000000LICENSE MANIFEST.in README.md setup.py Flask_Migrate.egg-info/PKG-INFO Flask_Migrate.egg-info/SOURCES.txt Flask_Migrate.egg-info/dependency_links.txt Flask_Migrate.egg-info/entry_points.txt Flask_Migrate.egg-info/not-zip-safe Flask_Migrate.egg-info/requires.txt Flask_Migrate.egg-info/top_level.txt flask_migrate/__init__.py flask_migrate/cli.py flask_migrate/templates/flask/README flask_migrate/templates/flask/alembic.ini.mako flask_migrate/templates/flask/env.py flask_migrate/templates/flask/script.py.mako flask_migrate/templates/flask-multidb/README flask_migrate/templates/flask-multidb/alembic.ini.mako flask_migrate/templates/flask-multidb/env.py flask_migrate/templates/flask-multidb/script.py.mako tests/__init__.py tests/__init__.pyc tests/app.py tests/app.pyc tests/app1.py tests/app1.pyc tests/app_compare_type1.py tests/app_compare_type1.pyc tests/app_compare_type2.py tests/app_compare_type2.pyc tests/app_custom_directory.py tests/app_custom_directory.pyc tests/app_flask_script.pyc tests/app_multidb.py tests/app_multidb.pyc tests/test_migrate.py tests/test_migrate.pyc tests/test_migrate_flaskcli.py tests/test_migrate_flaskcli.pyc tests/test_multidb_migrate.py tests/test_multidb_migrate.pyc tests/test_multidb_migrate_flaskcli.py tests/test_multidb_migrate_flaskcli.pycFlask-Migrate-2.1.1/Flask_Migrate.egg-info/top_level.txt0000644€´ä€_›j0000000001613151112065023407 0ustar migu778100000000000000flask_migrate Flask-Migrate-2.1.1/LICENSE0000644€´ä€_›j0000000207213022575400015467 0ustar migu778100000000000000The MIT License (MIT) Copyright (c) 2013 Miguel Grinberg Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Flask-Migrate-2.1.1/MANIFEST.in0000644€´ä€_›j0000000015513022575400016220 0ustar migu778100000000000000include README.md LICENSE flask_migrate/templates/flask/* \ flask_migrate/templates/flask-multidb/* tests/* Flask-Migrate-2.1.1/PKG-INFO0000644€´ä€_›j0000000160113151112065015551 0ustar migu778100000000000000Metadata-Version: 1.1 Name: Flask-Migrate Version: 2.1.1 Summary: SQLAlchemy database migrations for Flask applications using Alembic Home-page: http://github.com/miguelgrinberg/flask-migrate/ Author: Miguel Grinberg Author-email: miguelgrinberg50@gmail.com License: MIT Description: Flask-Migrate -------------- SQLAlchemy database migrations for Flask applications using Alembic. Platform: any Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 3 Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Classifier: Topic :: Software Development :: Libraries :: Python Modules Flask-Migrate-2.1.1/README.md0000644€´ä€_›j0000000437313136644632015761 0ustar migu778100000000000000Flask-Migrate ============= [![Build Status](https://travis-ci.org/miguelgrinberg/Flask-Migrate.png?branch=master)](https://travis-ci.org/miguelgrinberg/Flask-Migrate) Flask-Migrate is an extension that handles SQLAlchemy database migrations for Flask applications using Alembic. The database operations are provided as command line arguments for Flask-Script. Installation ------------ Install Flask-Migrate with `pip`: pip install Flask-Migrate Example ------- This is an example application that handles database migrations through Flask-Migrate: ```python from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db' db = SQLAlchemy(app) migrate = Migrate(app, db) class User(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(128)) ``` With the above application you can create the database or enable migrations if the database already exists with the following command: $ flask db init Note that the `FLASK_APP` environment variable must be set according to the Flask documentation for this command to work. This will add a `migrations` folder to your application. The contents of this folder need to be added to version control along with your other source files. You can then generate an initial migration: $ flask db migrate The migration script needs to be reviewed and edited, as Alembic currently does not detect every change you make to your models. In particular, Alembic is currently unable to detect indexes. Once finalized, the migration script also needs to be added to version control. Then you can apply the migration to the database: $ flask db upgrade Then each time the database models change repeat the `migrate` and `upgrade` commands. To sync the database in another system just refresh the `migrations` folder from source control and run the `upgrade` command. To see all the commands that are available run this command: $ flask db --help Resources --------- - [Documentation](http://pythonhosted.org/Flask-Migrate) - [pypi](https://pypi.python.org/pypi/Flask-Migrate) - [Change Log](https://github.com/miguelgrinberg/Flask-Migrate/blob/master/CHANGELOG.md) Flask-Migrate-2.1.1/setup.cfg0000644€´ä€_›j0000000007313151112065016277 0ustar migu778100000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 Flask-Migrate-2.1.1/setup.py0000644€´ä€_›j0000000251213151111633016170 0ustar migu778100000000000000""" Flask-Migrate -------------- SQLAlchemy database migrations for Flask applications using Alembic. """ from setuptools import setup setup( name='Flask-Migrate', version='2.1.1', url='http://github.com/miguelgrinberg/flask-migrate/', license='MIT', author='Miguel Grinberg', author_email='miguelgrinberg50@gmail.com', description=('SQLAlchemy database migrations for Flask applications ' 'using Alembic'), long_description=__doc__, packages=['flask_migrate'], zip_safe=False, include_package_data=True, platforms='any', install_requires=[ 'Flask>=0.9', 'Flask-SQLAlchemy>=1.0', 'alembic>=0.6' ], tests_require=[ 'Flask-Script>=0.6' ], entry_points={ 'flask.commands': [ 'db=flask_migrate.cli:db' ], }, test_suite="tests", classifiers=[ 'Environment :: Web Environment', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 3', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 'Topic :: Software Development :: Libraries :: Python Modules' ] ) Flask-Migrate-2.1.1/tests/0000755€´ä€_›j0000000000013151112065015620 5ustar migu778100000000000000Flask-Migrate-2.1.1/tests/__init__.py0000644€´ä€_›j0000000000113022575400017723 0ustar migu778100000000000000 Flask-Migrate-2.1.1/tests/__init__.pyc0000644€´ä€_›j0000000023213022575660020104 0ustar migu778100000000000000ó ûJXc@sdS(N((((sC/Users/migu7781/Documents/dev/flask/flask-migrate/tests/__init__.pytsFlask-Migrate-2.1.1/tests/app.py0000755€´ä€_›j0000000107313136477403016773 0ustar migu778100000000000000#!/bin/env python 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' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) migrate = Migrate(app, db) 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() Flask-Migrate-2.1.1/tests/app.pyc0000644€´ä€_›j0000000210013136477412017123 0ustar migu778100000000000000ó zYc@sÙddlmZddlmZddlmZddlmZmZee ƒZ de j d/Users/migu7781/Documents/dev/flask/flask-migrate/tests/app.pyRst__main__N(tflaskRtflask_sqlalchemyRt flask_scriptRt flask_migrateRRR tapptconfigtFalseRtmigratetmanagert add_commandtModelRtrun(((s>/Users/migu7781/Documents/dev/flask/flask-migrate/tests/app.pyts      Flask-Migrate-2.1.1/tests/app1.py0000755€´ä€_›j0000000063113136477772017064 0ustar migu778100000000000000#!/bin/env python from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) migrate = Migrate(app, db) class User(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(128)) Flask-Migrate-2.1.1/tests/app1.pyc0000644€´ä€_›j0000000157013136477773017230 0ustar migu778100000000000000ó úzYc@sŽddlmZddlmZddlmZeeƒZdejds    Flask-Migrate-2.1.1/tests/app_compare_type1.py0000755€´ä€_›j0000000107413022575400021612 0ustar migu778100000000000000from 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' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False 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() Flask-Migrate-2.1.1/tests/app_compare_type1.pyc0000644€´ä€_›j0000000217013022575660021760 0ustar migu778100000000000000ó ûJXc@sßddlmZddlmZddlmZddlmZmZee ƒZ de j ds      Flask-Migrate-2.1.1/tests/app_compare_type2.py0000755€´ä€_›j0000000107313022575400021612 0ustar migu778100000000000000from 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' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False 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() Flask-Migrate-2.1.1/tests/app_compare_type2.pyc0000644€´ä€_›j0000000217013022575660021761 0ustar migu778100000000000000ó ûJXc@sßddlmZddlmZddlmZddlmZmZee ƒZ de j ds      Flask-Migrate-2.1.1/tests/app_custom_directory.py0000755€´ä€_›j0000000112313022575400022433 0ustar migu778100000000000000from 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' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) migrate = Migrate(app, db, directory='temp_folder/temp_migrations') 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() Flask-Migrate-2.1.1/tests/app_custom_directory.pyc0000644€´ä€_›j0000000222613022575660022610 0ustar migu778100000000000000ó ûJXc@sßddlmZddlmZddlmZddlmZmZee ƒZ de j ds      Flask-Migrate-2.1.1/tests/app_flask_script.pyc0000644€´ä€_›j0000000213213136476325021676 0ustar migu778100000000000000ó VrzYc@sÙddlmZddlmZddlmZddlmZmZee ƒZ de j ds      Flask-Migrate-2.1.1/tests/app_multidb.py0000755€´ä€_›j0000000141313022575400020477 0ustar migu778100000000000000#!/bin/env python 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:///app1.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['SQLALCHEMY_BINDS'] = { "db1": "sqlite:///app2.db", } db = SQLAlchemy(app) class User(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(128)) class Group(db.Model): __bind_key__ = 'db1' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(128)) migrate = Migrate(app, db) manager = Manager(app) manager.add_command('db', MigrateCommand) if __name__ == '__main__': manager.run() Flask-Migrate-2.1.1/tests/app_multidb.pyc0000644€´ä€_›j0000000273713022575660020661 0ustar migu778100000000000000ó ûJXc@sddlmZddlmZddlmZddlmZmZee ƒZ de j deZdZejejdeƒZejejdƒƒZ RS(RR i€( R R t __bind_key__R RRRRRR(((sF/Users/migu7781/Documents/dev/flask/flask-migrate/tests/app_multidb.pyRsR t__main__N(tflaskRtflask_sqlalchemyRt flask_scriptRt flask_migrateRRR tapptconfigtFalseR tModelR Rtmigratetmanagert add_commandtrun(((sF/Users/migu7781/Documents/dev/flask/flask-migrate/tests/app_multidb.pyts       Flask-Migrate-2.1.1/tests/test_migrate.py0000644€´ä€_›j0000000526513136477403020706 0ustar migu778100000000000000import 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): def setUp(self): os.chdir(os.path.split(os.path.abspath(__file__))[0]) try: os.remove('app.db') except OSError: pass try: shutil.rmtree('migrations') except OSError: pass try: shutil.rmtree('temp_folder') except OSError: pass def tearDown(self): try: os.remove('app.db') except OSError: pass try: 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 self.assertEqual(len(alembic_version), 3) for v in alembic_version: 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) Flask-Migrate-2.1.1/tests/test_migrate.pyc0000644€´ä€_›j0000000776213136477412021055 0ustar migu778100000000000000ó zYc@sbddlZddlZddlZddlZddlZd„Zdejfd„ƒYZdS(iÿÿÿÿNcCsOtjtj|ƒdtjdtjƒ}|jƒ\}}|||jƒfS(sARun a command and return a tuple with (stdout, stderr, exit_code)tstdouttstderr(t subprocesstPopentshlextsplittPIPEt communicatetwait(tcmdtprocessRR((sG/Users/migu7781/Documents/dev/flask/flask-migrate/tests/test_migrate.pytrun_cmds t TestMigratecBs>eZd„Zd„Zd„Zd„Zd„Zd„ZRS(cCsœtjtjjtjjtƒƒdƒytjdƒWntk rMnXytj dƒWntk rrnXytj dƒWntk r—nXdS(Nisapp.dbt migrationst temp_folder( tostchdirtpathRtabspatht__file__tremovetOSErrortshutiltrmtree(tself((sG/Users/migu7781/Documents/dev/flask/flask-migrate/tests/test_migrate.pytsetUps)   cCssytjdƒWntk r$nXytjdƒWntk rInXytjdƒWntk rnnXdS(Nsapp.dbR R(RRRRR(R((sG/Users/migu7781/Documents/dev/flask/flask-migrate/tests/test_migrate.pyttearDown s   cCsQddlm}|jt|ƒdƒx$|D]}|jt|tƒƒq-WdS(Niÿÿÿÿ(talembic_versioni(t flask_migrateRt assertEqualtlent assertTruet isinstancetint(RRtv((sG/Users/migu7781/Documents/dev/flask/flask-migrate/tests/test_migrate.pyttest_alembic_version.s cCs¸tdƒ\}}}|j|dkƒtdƒ\}}}|j|dkƒtdƒ\}}}|j|dkƒddlm}m}|jj|ddƒƒ|jjƒdS( Nspython app.py db initispython app.py db migratespython app.py db upgradei(tdbtUsertnamettest(R RtappR$R%tsessiontaddtcommit(RtotetsR$R%((sG/Users/migu7781/Documents/dev/flask/flask-migrate/tests/test_migrate.pyttest_migrate_upgrade4scCs¸tdƒ\}}}|j|dkƒtdƒ\}}}|j|dkƒtdƒ\}}}|j|dkƒddlm}m}|jj|ddƒƒ|jjƒdS( Ns&python app_custom_directory.py db initis)python app_custom_directory.py db migrates)python app_custom_directory.py db upgradei(R$R%R&R'(R Rtapp_custom_directoryR$R%R)R*R+(RR,R-R.R$R%((sG/Users/migu7781/Documents/dev/flask/flask-migrate/tests/test_migrate.pyttest_custom_directory@scCs·tdƒ\}}}|j|dkƒtdƒ\}}}|j|dkƒtdƒ\}}}|j|dkƒtdƒ\}}}|j|dkƒ|jd|kƒdS(Ns#python app_compare_type1.py db initis&python app_compare_type1.py db migrates&python app_compare_type1.py db upgrades&python app_compare_type2.py db migratesBDetected type change from VARCHAR(length=128) to String(length=10)(R R(RR,R-R.((sG/Users/migu7781/Documents/dev/flask/flask-migrate/tests/test_migrate.pyttest_compare_typeLs (t__name__t __module__RRR#R/R1R2(((sG/Users/migu7781/Documents/dev/flask/flask-migrate/tests/test_migrate.pyR s     (RRtunittestRRR tTestCaseR (((sG/Users/migu7781/Documents/dev/flask/flask-migrate/tests/test_migrate.pyts      Flask-Migrate-2.1.1/tests/test_migrate_flaskcli.py0000644€´ä€_›j0000000536013022575400022540 0ustar migu778100000000000000import os import shutil import unittest import subprocess import shlex def run_cmd(app, cmd): """Run a command and return a tuple with (stdout, stderr, exit_code)""" os.environ['FLASK_APP'] = app 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): def setUp(self): os.chdir(os.path.split(os.path.abspath(__file__))[0]) try: os.remove('app.db') except OSError: pass try: shutil.rmtree('migrations') except OSError: pass try: shutil.rmtree('temp_folder') except OSError: pass def tearDown(self): try: os.remove('app.db') except OSError: pass try: 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 self.assertEqual(len(alembic_version), 3) for v in alembic_version: self.assertTrue(isinstance(v, int)) def test_migrate_upgrade(self): (o, e, s) = run_cmd('app.py', 'flask db init') self.assertTrue(s == 0) (o, e, s) = run_cmd('app.py', 'flask db migrate') self.assertTrue(s == 0) (o, e, s) = run_cmd('app.py', 'flask 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('app_custom_directory.py', 'flask db init') self.assertTrue(s == 0) (o, e, s) = run_cmd('app_custom_directory.py', 'flask db migrate') self.assertTrue(s == 0) (o, e, s) = run_cmd('app_custom_directory.py', 'flask 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('app_compare_type1.py', 'flask db init') self.assertTrue(s == 0) (o, e, s) = run_cmd('app_compare_type1.py', 'flask db migrate') self.assertTrue(s == 0) (o, e, s) = run_cmd('app_compare_type1.py', 'flask db upgrade') self.assertTrue(s == 0) (o, e, s) = run_cmd('app_compare_type2.py', 'flask db migrate') self.assertTrue(s == 0) self.assertTrue(b'Detected type change from VARCHAR(length=128) ' b'to String(length=10)' in e) Flask-Migrate-2.1.1/tests/test_migrate_flaskcli.pyc0000644€´ä€_›j0000001003513022575660022706 0ustar migu778100000000000000ó ûJXc@sbddlZddlZddlZddlZddlZd„Zdejfd„ƒYZdS(iÿÿÿÿNcCs\|tjdeZd„Zd„Zd„Zd„Zd„Zd„ZRS(cCsœtjtjjtjjtƒƒdƒytjdƒWntk rMnXytj dƒWntk rrnXytj dƒWntk r—nXdS(Nisapp.dbt migrationst temp_folder( RtchdirtpathRtabspatht__file__tremovetOSErrortshutiltrmtree(tself((sP/Users/migu7781/Documents/dev/flask/flask-migrate/tests/test_migrate_flaskcli.pytsetUps)   cCssytjdƒWntk r$nXytjdƒWntk rInXytjdƒWntk rnnXdS(Nsapp.dbRR(RRRRR(R((sP/Users/migu7781/Documents/dev/flask/flask-migrate/tests/test_migrate_flaskcli.pyttearDown!s   cCsQddlm}|jt|ƒdƒx$|D]}|jt|tƒƒq-WdS(Niÿÿÿÿ(talembic_versioni(t flask_migrateRt assertEqualtlent assertTruet isinstancetint(RRtv((sP/Users/migu7781/Documents/dev/flask/flask-migrate/tests/test_migrate_flaskcli.pyttest_alembic_version/s cCsÁtddƒ\}}}|j|dkƒtddƒ\}}}|j|dkƒtddƒ\}}}|j|dkƒddlm}m}|jj|dd ƒƒ|jjƒdS( Nsapp.pys flask db initisflask db migratesflask db upgradei(tdbtUsertnamettest(RR"R R'R(tsessiontaddtcommit(RtotetsR'R(((sP/Users/migu7781/Documents/dev/flask/flask-migrate/tests/test_migrate_flaskcli.pyttest_migrate_upgrade5scCsÁtddƒ\}}}|j|dkƒtddƒ\}}}|j|dkƒtddƒ\}}}|j|dkƒddlm}m}|jj|dd ƒƒ|jjƒdS( Nsapp_custom_directory.pys flask db initisflask db migratesflask db upgradei(R'R(R)R*(RR"tapp_custom_directoryR'R(R+R,R-(RR.R/R0R'R(((sP/Users/migu7781/Documents/dev/flask/flask-migrate/tests/test_migrate_flaskcli.pyttest_custom_directoryAscCsÃtddƒ\}}}|j|dkƒtddƒ\}}}|j|dkƒtddƒ\}}}|j|dkƒtddƒ\}}}|j|dkƒ|jd|kƒdS(Nsapp_compare_type1.pys flask db initisflask db migratesflask db upgradesapp_compare_type2.pysBDetected type change from VARCHAR(length=128) to String(length=10)(RR"(RR.R/R0((sP/Users/migu7781/Documents/dev/flask/flask-migrate/tests/test_migrate_flaskcli.pyttest_compare_typeMs (t__name__t __module__RRR&R1R3R4(((sP/Users/migu7781/Documents/dev/flask/flask-migrate/tests/test_migrate_flaskcli.pyRs     (RRtunittestRRRtTestCaseR(((sP/Users/migu7781/Documents/dev/flask/flask-migrate/tests/test_migrate_flaskcli.pyts      Flask-Migrate-2.1.1/tests/test_multidb_migrate.py0000644€´ä€_›j0000000535713100472657022425 0ustar migu778100000000000000import os import shutil import unittest import subprocess import shlex import sqlite3 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): def setUp(self): os.chdir(os.path.split(os.path.abspath(__file__))[0]) try: os.remove('app1.db') os.remove('app2.db') except OSError: pass try: shutil.rmtree('migrations') except OSError: pass def tearDown(self): try: os.remove('app1.db') os.remove('app2.db') except OSError: pass try: shutil.rmtree('migrations') except OSError: pass def test_multidb_migrate_upgrade(self): (o, e, s) = run_cmd('python app_multidb.py db init --multidb') self.assertTrue(s == 0) (o, e, s) = run_cmd('python app_multidb.py db migrate') self.assertTrue(s == 0) (o, e, s) = run_cmd('python app_multidb.py db upgrade') self.assertTrue(s == 0) # ensure the tables are in the correct databases conn1 = sqlite3.connect('app1.db') c = conn1.cursor() c.execute('select name from sqlite_master') tables = c.fetchall() conn1.close() self.assertIn(('alembic_version',), tables) self.assertIn(('user',), tables) conn2 = sqlite3.connect('app2.db') c = conn2.cursor() c.execute('select name from sqlite_master') tables = c.fetchall() conn2.close() self.assertIn(('alembic_version',), tables) self.assertIn(('group',), tables) # ensure the databases can be written to from .app_multidb import db, User, Group db.session.add(User(name='test')) db.session.add(Group(name='group')) db.session.commit() # ensure the downgrade works (o, e, s) = run_cmd('python app_multidb.py db downgrade') self.assertTrue(s == 0) conn1 = sqlite3.connect('app1.db') c = conn1.cursor() c.execute('select name from sqlite_master') tables = c.fetchall() conn1.close() self.assertIn(('alembic_version',), tables) self.assertNotIn(('user',), tables) conn2 = sqlite3.connect('app2.db') c = conn2.cursor() c.execute('select name from sqlite_master') tables = c.fetchall() conn2.close() self.assertIn(('alembic_version',), tables) self.assertNotIn(('group',), tables) Flask-Migrate-2.1.1/tests/test_multidb_migrate.pyc0000644€´ä€_›j0000000606113100731363022551 0ustar migu778100000000000000ó ¯uYc@snddlZddlZddlZddlZddlZddlZd„Zdejfd„ƒYZdS(iÿÿÿÿNcCsOtjtj|ƒdtjdtjƒ}|jƒ\}}|||jƒfS(sARun a command and return a tuple with (stdout, stderr, exit_code)tstdouttstderr(t subprocesstPopentshlextsplittPIPEt communicatetwait(tcmdtprocessRR((stests/test_multidb_migrate.pytrun_cmd s t TestMigratecBs#eZd„Zd„Zd„ZRS(cCs„tjtjjtjjtƒƒdƒytjdƒtjdƒWntk rZnXytj dƒWntk rnXdS(Nisapp1.dbsapp2.dbt migrations( tostchdirtpathRtabspatht__file__tremovetOSErrortshutiltrmtree(tself((stests/test_multidb_migrate.pytsetUps)   cCs[ytjdƒtjdƒWntk r1nXytjdƒWntk rVnXdS(Nsapp1.dbsapp2.dbR (RRRRR(R((stests/test_multidb_migrate.pyttearDowns   c Cswtdƒ\}}}|j|dkƒtdƒ\}}}|j|dkƒtdƒ\}}}|j|dkƒtjdƒ}|jƒ}|jdƒ|jƒ}|jƒ|jd|ƒ|jd|ƒtjd ƒ}|jƒ}|jdƒ|jƒ}|jƒ|jd|ƒ|jd|ƒd d l m }m } m } |j j| d dƒƒ|j j| d d ƒƒ|j jƒtdƒ\}}}|j|dkƒtjdƒ}|jƒ}|jdƒ|jƒ}|jƒ|jd|ƒ|jd|ƒtjd ƒ}|jƒ}|jdƒ|jƒ}|jƒ|jd|ƒ|jd|ƒdS(Ns'python app_multidb.py db init --multidbis python app_multidb.py db migrates python app_multidb.py db upgradesapp1.dbsselect name from sqlite_mastertalembic_versiontusersapp2.dbtgroupi(tdbtUsertGrouptnamettests"python app_multidb.py db downgrade(salembic_version(R(salembic_version(sgroup(salembic_version(R(salembic_version(sgroup(R t assertTruetsqlite3tconnecttcursortexecutetfetchalltclosetassertInt app_multidbRRRtsessiontaddtcommitt assertNotIn( Rtotetstconn1tcttablestconn2RRR((stests/test_multidb_migrate.pyttest_multidb_migrate_upgrade)sP                 (t__name__t __module__RRR6(((stests/test_multidb_migrate.pyR s ( RRtunittestRRR#R tTestCaseR (((stests/test_multidb_migrate.pyts       Flask-Migrate-2.1.1/tests/test_multidb_migrate_flaskcli.py0000644€´ä€_›j0000000543613100472657024273 0ustar migu778100000000000000import os import shutil import unittest import subprocess import shlex import sqlite3 def run_cmd(app, cmd): """Run a command and return a tuple with (stdout, stderr, exit_code)""" os.environ['FLASK_APP'] = app 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): def setUp(self): os.chdir(os.path.split(os.path.abspath(__file__))[0]) try: os.remove('app1.db') os.remove('app2.db') except OSError: pass try: shutil.rmtree('migrations') except OSError: pass def tearDown(self): try: os.remove('app1.db') os.remove('app2.db') except OSError: pass try: shutil.rmtree('migrations') except OSError: pass def test_multidb_migrate_upgrade(self): (o, e, s) = run_cmd('app_multidb.py', 'flask db init --multidb') self.assertTrue(s == 0) (o, e, s) = run_cmd('app_multidb.py', 'flask db migrate') self.assertTrue(s == 0) (o, e, s) = run_cmd('app_multidb.py', 'flask db upgrade') self.assertTrue(s == 0) # ensure the tables are in the correct databases conn1 = sqlite3.connect('app1.db') c = conn1.cursor() c.execute('select name from sqlite_master') tables = c.fetchall() conn1.close() self.assertIn(('alembic_version',), tables) self.assertIn(('user',), tables) conn2 = sqlite3.connect('app2.db') c = conn2.cursor() c.execute('select name from sqlite_master') tables = c.fetchall() conn2.close() self.assertIn(('alembic_version',), tables) self.assertIn(('group',), tables) # ensure the databases can be written to from .app_multidb import db, User, Group db.session.add(User(name='test')) db.session.add(Group(name='group')) db.session.commit() # ensure the downgrade works (o, e, s) = run_cmd('app_multidb.py', 'flask db downgrade') self.assertTrue(s == 0) conn1 = sqlite3.connect('app1.db') c = conn1.cursor() c.execute('select name from sqlite_master') tables = c.fetchall() conn1.close() self.assertIn(('alembic_version',), tables) self.assertNotIn(('user',), tables) conn2 = sqlite3.connect('app2.db') c = conn2.cursor() c.execute('select name from sqlite_master') tables = c.fetchall() conn2.close() self.assertIn(('alembic_version',), tables) self.assertNotIn(('group',), tables) Flask-Migrate-2.1.1/tests/test_multidb_migrate_flaskcli.pyc0000644€´ä€_›j0000000620413100731363024420 0ustar migu778100000000000000ó ¯uYc@snddlZddlZddlZddlZddlZddlZd„Zdejfd„ƒYZdS(iÿÿÿÿNcCs\|tjds