def process_revision_directives(context, rev, generate_revisions): generate_revisions[:] = [ ops.MigrationScript( util.rev_id(), ops.UpgradeOps(), ops.DowngradeOps(), version_path=os.path.join(_get_staging_directory(), "model1"), head="model1@head", ), ops.MigrationScript( util.rev_id(), ops.UpgradeOps(), ops.DowngradeOps(), version_path=os.path.join(_get_staging_directory(), "model2"), head="model2@head", ), ops.MigrationScript( util.rev_id(), ops.UpgradeOps(), ops.DowngradeOps(), version_path=os.path.join(_get_staging_directory(), "model3"), head="model3@head", ), ]
def _expect_default(self, c_expected, col, seq=None): Table('t', self.metadata, col) if seq: seq._set_metadata(self.metadata) self.metadata.create_all(config.db) insp = Inspector.from_engine(config.db) uo = ops.UpgradeOps(ops=[]) _compare_tables(set([(None, 't')]), set([]), insp, self.metadata, uo, self.autogen_context) diffs = uo.as_diffs() tab = diffs[0][1] eq_( _render_server_default_for_compare(tab.c.x.server_default, tab.c.x, self.autogen_context), c_expected) insp = Inspector.from_engine(config.db) uo = ops.UpgradeOps(ops=[]) m2 = MetaData() Table('t', m2, Column('x', BigInteger())) _compare_tables(set([(None, 't')]), set([(None, 't')]), insp, m2, uo, self.autogen_context) diffs = uo.as_diffs() server_default = diffs[0][0][4]['existing_server_default'] eq_( _render_server_default_for_compare(server_default, tab.c.x, self.autogen_context), c_expected)
def test_upgrade_downgrade_ops_list_accessors(self): u1 = ops.UpgradeOps(ops=[]) d1 = ops.DowngradeOps(ops=[]) m1 = ops.MigrationScript("somerev", u1, d1) is_(m1.upgrade_ops, u1) is_(m1.downgrade_ops, d1) u2 = ops.UpgradeOps(ops=[]) d2 = ops.DowngradeOps(ops=[]) m1._upgrade_ops.append(u2) m1._downgrade_ops.append(d2) assert_raises_message( ValueError, "This MigrationScript instance has a multiple-entry list for " "UpgradeOps; please use the upgrade_ops_list attribute.", getattr, m1, "upgrade_ops", ) assert_raises_message( ValueError, "This MigrationScript instance has a multiple-entry list for " "DowngradeOps; please use the downgrade_ops_list attribute.", getattr, m1, "downgrade_ops", ) eq_(m1.upgrade_ops_list, [u1, u2]) eq_(m1.downgrade_ops_list, [d1, d2])
def _migration_script_ops(context, directive, phase): """Generate a new ops.MigrationScript() for a given phase. E.g. given an ops.MigrationScript() directive from a vanilla autogenerate and an expand/contract phase name, produce a new ops.MigrationScript() which contains only those sub-directives appropriate to "expand" or "contract". Also ensure that the branch directory exists and that the correct branch labels/depends_on/head revision are set up. """ version_path = cli._get_version_branch_path(context.config, phase) autogen_kwargs = {} cli._check_bootstrap_new_branch(phase, version_path, autogen_kwargs) op = ops.MigrationScript(new_rev_id(), ops.UpgradeOps(ops=[ d for d in _assign_directives( context, directive.upgrade_ops.ops, phase) ]), ops.DowngradeOps(ops=[]), message=directive.message, **autogen_kwargs) if not op.upgrade_ops.is_empty(): return op
def test_all_traverse(self): writer = autogenerate.Rewriter() mocker = mock.Mock(side_effect=lambda context, revision, op: op) writer.rewrites(ops.MigrateOperation)(mocker) addcolop = ops.AddColumnOp('t1', sa.Column('x', sa.Integer())) directives = [ ops.MigrationScript( util.rev_id(), ops.UpgradeOps(ops=[ops.ModifyTableOps('t1', ops=[addcolop])]), ops.DowngradeOps(ops=[]), ) ] ctx, rev = mock.Mock(), mock.Mock() writer(ctx, rev, directives) eq_(mocker.mock_calls, [ mock.call(ctx, rev, directives[0]), mock.call(ctx, rev, directives[0].upgrade_ops), mock.call(ctx, rev, directives[0].upgrade_ops.ops[0]), mock.call(ctx, rev, addcolop), mock.call(ctx, rev, directives[0].downgrade_ops), ])
def process_revision_directives(context, rev, generate_revisions): existing_upgrades = generate_revisions[0].upgrade_ops existing_downgrades = generate_revisions[0].downgrade_ops # model1 will run the upgrades, e.g. create the table, # model2 will run the downgrades as upgrades, e.g. drop # the table again generate_revisions[:] = [ ops.MigrationScript( util.rev_id(), existing_upgrades, ops.DowngradeOps(), version_path=os.path.join(_get_staging_directory(), "model1"), head="model1@head", ), ops.MigrationScript( util.rev_id(), ops.UpgradeOps(ops=existing_downgrades.ops), ops.DowngradeOps(), version_path=os.path.join(_get_staging_directory(), "model2"), head="model2@head", ), ]
def test_uses_custom_compare_type_function(self): my_compare_type = mock.Mock() self.context._user_compare_type = my_compare_type uo = ops.UpgradeOps(ops=[]) ctx = self.autogen_context autogenerate._produce_net_changes(ctx, uo) first_table = self.m2.tables["sometable"] first_column = first_table.columns["id"] eq_(len(my_compare_type.mock_calls), 2) # We'll just test the first call _, args, _ = my_compare_type.mock_calls[0] ( context, inspected_column, metadata_column, inspected_type, metadata_type, ) = args eq_(context, self.context) eq_(metadata_column, first_column) eq_(metadata_type, first_column.type) eq_(inspected_column.name, first_column.name) eq_(type(inspected_type), INTEGER)
def _fixture(self, m1, m2, include_schemas=False, opts=None, object_filters=_default_object_filters): self.metadata, model_metadata = m1, m2 self.metadata.create_all(self.bind) with self.bind.connect() as conn: ctx_opts = { 'compare_type': True, 'compare_server_default': True, 'target_metadata': model_metadata, 'upgrade_token': "upgrades", 'downgrade_token': "downgrades", 'alembic_module_prefix': 'op.', 'sqlalchemy_module_prefix': 'sa.', 'include_object': object_filters, 'include_schemas': include_schemas } if opts: ctx_opts.update(opts) self.context = context = MigrationContext.configure( connection=conn, opts=ctx_opts) autogen_context = api.AutogenContext(context, model_metadata) uo = ops.UpgradeOps(ops=[]) autogenerate._produce_net_changes(autogen_context, uo) return uo.as_diffs()
def _expect_default(self, c_expected, col, seq=None): Table("t", self.metadata, col) self.autogen_context.metadata = self.metadata if seq: seq._set_metadata(self.metadata) self.metadata.create_all(config.db) insp = inspect(config.db) uo = ops.UpgradeOps(ops=[]) _compare_tables( set([(None, "t")]), set([]), insp, uo, self.autogen_context ) diffs = uo.as_diffs() tab = diffs[0][1] eq_( _render_server_default_for_compare( tab.c.x.server_default, tab.c.x, self.autogen_context ), c_expected, ) insp = inspect(config.db) uo = ops.UpgradeOps(ops=[]) m2 = MetaData() Table("t", m2, Column("x", BigInteger())) self.autogen_context.metadata = m2 _compare_tables( set([(None, "t")]), set([(None, "t")]), insp, uo, self.autogen_context, ) diffs = uo.as_diffs() server_default = diffs[0][0][4]["existing_server_default"] eq_( _render_server_default_for_compare( server_default, tab.c.x, self.autogen_context ), c_expected, )
def test_diffs(self): """test generation of diff rules""" metadata = self.m2 self._update_context(include_schemas=True, ) uo = ops.UpgradeOps(ops=[]) autogenerate._produce_net_changes(self.autogen_context, uo) diffs = uo.as_diffs() eq_(diffs[0], ('add_table', metadata.tables['%s.item' % self.schema])) eq_(diffs[1][0], 'remove_table') eq_(diffs[1][1].name, "extra") eq_(diffs[2][0], "add_column") eq_(diffs[2][1], self.schema) eq_(diffs[2][2], "address") eq_(diffs[2][3], metadata.tables['%s.address' % self.schema].c.street) eq_(diffs[3][0], "add_constraint") eq_(diffs[3][1].name, "uq_email") eq_(diffs[4][0], "add_column") eq_(diffs[4][1], self.schema) eq_(diffs[4][2], "order") eq_(diffs[4][3], metadata.tables['%s.order' % self.schema].c.user_id) eq_(diffs[5][0][0], "modify_type") eq_(diffs[5][0][1], self.schema) eq_(diffs[5][0][2], "order") eq_(diffs[5][0][3], "amount") eq_(repr(diffs[5][0][5]), "NUMERIC(precision=8, scale=2)") eq_(repr(diffs[5][0][6]), "Numeric(precision=10, scale=2)") self._assert_fk_diff(diffs[6], "add_fk", "order", ["user_id"], "user", ["id"], source_schema=config.test_schema) eq_(diffs[7][0][0], "modify_default") eq_(diffs[7][0][1], self.schema) eq_(diffs[7][0][2], "user") eq_(diffs[7][0][3], "a1") eq_(diffs[7][0][6].arg, "x") eq_(diffs[8][0][0], 'modify_nullable') eq_(diffs[8][0][5], True) eq_(diffs[8][0][6], False) eq_(diffs[9][0], 'remove_index') eq_(diffs[9][1].name, 'pw_idx') eq_(diffs[10][0], 'remove_column') eq_(diffs[10][3].name, 'pw')
def test_version_table_in_target(self): Table( self.version_table_name, self.m2, Column('x', Integer), schema=self.version_table_schema) ctx = self.autogen_context uo = ops.UpgradeOps(ops=[]) autogenerate._produce_net_changes(ctx, uo) eq_(uo.as_diffs(), [])
def test_chained_ops(self): writer1 = autogenerate.Rewriter() writer2 = autogenerate.Rewriter() @writer1.rewrites(ops.AddColumnOp) def add_column_nullable(context, revision, op): if op.column.nullable: return op else: op.column.nullable = True return [ op, ops.AlterColumnOp( op.table_name, op.column.name, modify_nullable=False, existing_type=op.column.type, ), ] @writer2.rewrites(ops.AddColumnOp) def add_column_idx(context, revision, op): idx_op = ops.CreateIndexOp("ixt", op.table_name, [op.column.name]) return [op, idx_op] directives = [ ops.MigrationScript( util.rev_id(), ops.UpgradeOps(ops=[ ops.ModifyTableOps( "t1", ops=[ ops.AddColumnOp( "t1", sa.Column("x", sa.Integer(), nullable=False), ) ], ) ]), ops.DowngradeOps(ops=[]), ) ] ctx, rev = mock.Mock(), mock.Mock() writer1.chain(writer2)(ctx, rev, directives) eq_( autogenerate.render_python_code(directives[0].upgrade_ops), "# ### commands auto generated by Alembic - please adjust! ###\n" " op.add_column('t1', " "sa.Column('x', sa.Integer(), nullable=True))\n" " op.create_index('ixt', 't1', ['x'], unique=False)\n" " op.alter_column('t1', 'x',\n" " existing_type=sa.Integer(),\n" " nullable=False)\n" " # ### end Alembic commands ###", )
def test_dont_barf_on_already_reflected(self): from sqlalchemy.util import OrderedSet inspector = Inspector.from_engine(self.bind) uo = ops.UpgradeOps(ops=[]) autogenerate.compare._compare_tables( OrderedSet([(None, 'extra'), (None, 'user')]), OrderedSet(), inspector, uo, self.autogen_context) eq_([(rec[0], rec[1].name) for rec in uo.as_diffs()], [('remove_table', 'extra'), ('remove_table', 'user')])
def test_diffs(self): """test generation of diff rules""" metadata = self.m2 uo = ops.UpgradeOps(ops=[]) ctx = self.autogen_context autogenerate._produce_net_changes(ctx, uo) diffs = uo.as_diffs() eq_(diffs[0], ("add_table", metadata.tables["item"])) eq_(diffs[1][0], "remove_table") eq_(diffs[1][1].name, "extra") eq_(diffs[2][0], "add_column") eq_(diffs[2][1], None) eq_(diffs[2][2], "address") eq_(diffs[2][3], metadata.tables["address"].c.street) eq_(diffs[3][0], "add_constraint") eq_(diffs[3][1].name, "uq_email") eq_(diffs[4][0], "add_column") eq_(diffs[4][1], None) eq_(diffs[4][2], "order") eq_(diffs[4][3], metadata.tables["order"].c.user_id) eq_(diffs[5][0][0], "modify_type") eq_(diffs[5][0][1], None) eq_(diffs[5][0][2], "order") eq_(diffs[5][0][3], "amount") eq_(repr(diffs[5][0][5]), "NUMERIC(precision=8, scale=2)") eq_(repr(diffs[5][0][6]), "Numeric(precision=10, scale=2)") self._assert_fk_diff( diffs[6], "add_fk", "order", ["user_id"], "user", ["id"] ) eq_(diffs[7][0][0], "modify_default") eq_(diffs[7][0][1], None) eq_(diffs[7][0][2], "user") eq_(diffs[7][0][3], "a1") eq_(diffs[7][0][6].arg, "x") eq_(diffs[8][0][0], "modify_nullable") eq_(diffs[8][0][5], True) eq_(diffs[8][0][6], False) eq_(diffs[9][0], "remove_index") eq_(diffs[9][1].name, "pw_idx") eq_(diffs[10][0], "remove_column") eq_(diffs[10][3].name, "pw") eq_(diffs[10][3].table.name, "user") assert isinstance(diffs[10][3].type, String)
def process_revision_directives(context, rev, generate_revisions): generate_revisions[0].message = "test programatic" generate_revisions[0].upgrade_ops = ops.UpgradeOps(ops=[ ops.CreateTableOp('test_table', [ sa.Column('id', sa.Integer(), primary_key=True), sa.Column('name', sa.String(50), nullable=False) ]), ]) generate_revisions[0].downgrade_ops = ops.DowngradeOps( ops=[ops.DropTableOp('test_table')])
def _fixture( self, m1, m2, include_schemas=False, opts=None, object_filters=_default_object_filters, name_filters=_default_name_filters, return_ops=False, max_identifier_length=None, ): if max_identifier_length: dialect = self.bind.dialect existing_length = dialect.max_identifier_length dialect.max_identifier_length = ( dialect._user_defined_max_identifier_length ) = max_identifier_length try: self._alembic_metadata, model_metadata = m1, m2 for m in util.to_list(self._alembic_metadata): m.create_all(self.bind) with self.bind.connect() as conn: ctx_opts = { "compare_type": True, "compare_server_default": True, "target_metadata": model_metadata, "upgrade_token": "upgrades", "downgrade_token": "downgrades", "alembic_module_prefix": "op.", "sqlalchemy_module_prefix": "sa.", "include_object": object_filters, "include_name": name_filters, "include_schemas": include_schemas, } if opts: ctx_opts.update(opts) self.context = context = MigrationContext.configure( connection=conn, opts=ctx_opts) autogen_context = api.AutogenContext(context, model_metadata) uo = ops.UpgradeOps(ops=[]) autogenerate._produce_net_changes(autogen_context, uo) if return_ops: return uo else: return uo.as_diffs() finally: if max_identifier_length: dialect = self.bind.dialect dialect.max_identifier_length = ( dialect._user_defined_max_identifier_length ) = existing_length
def test_autogen(self): uo = ops.UpgradeOps(ops=[]) ctx = self.autogen_context autogenerate._produce_net_changes(ctx, uo) diffs = uo.as_diffs() eq_(diffs[0][0], "add_table") eq_(diffs[0][1].name, "sometable") eq_(diffs[1][0], "add_column") eq_(diffs[1][3].key, "otherkey")
def test_no_needless_pass(self): writer1 = autogenerate.Rewriter() @writer1.rewrites(ops.AlterColumnOp) def rewrite_alter_column(context, revision, op): return [] directives = [ ops.MigrationScript( util.rev_id(), ops.UpgradeOps( ops=[ ops.ModifyTableOps( "t1", ops=[ ops.AlterColumnOp( "foo", "bar", modify_nullable=False, existing_type=sa.Integer(), ), ops.AlterColumnOp( "foo", "bar", modify_nullable=False, existing_type=sa.Integer(), ), ], ), ops.ModifyTableOps( "t1", ops=[ ops.AlterColumnOp( "foo", "bar", modify_nullable=False, existing_type=sa.Integer(), ) ], ), ] ), ops.DowngradeOps(ops=[]), ) ] ctx, rev = mock.Mock(), mock.Mock() writer1(ctx, rev, directives) eq_( autogenerate.render_python_code(directives[0].upgrade_ops), "# ### commands auto generated by Alembic - please adjust! ###\n" " pass\n" " # ### end Alembic commands ###", )
def test_column_type_modified_custom_compare_type_returns_True(self): my_compare_type = Mock() my_compare_type.return_value = True self.context._user_compare_type = my_compare_type ctx = self.autogen_context uo = ops.UpgradeOps(ops=[]) autogenerate._produce_net_changes(ctx, uo) diffs = uo.as_diffs() eq_(diffs[0][0][0], 'modify_type') eq_(diffs[1][0][0], 'modify_type')
def _action(): """Create a migration to update permissions if needed""" service_name = app.config['TS_SERVICE_NAME'] perms = permissions.get_permissions_info(db_session, permission_model) if _needs_update(perms): from alembic.config import Config from alembic.script import ScriptDirectory from alembic.operations import ops from alembic.util import rev_id as alembic_rev_id from alembic.autogenerate.api import render_python_code insert_tpl = ( "INSERT INTO permission " "(uuid, service_name, permission) VALUES " "('{uuid}'::uuid, '{service_name}', '{permission}')" ) update_tpl = ( "UPDATE permission " "SET is_sent = false, is_deleted = {is_deleted} " "WHERE uuid = '{uuid}'::uuid" ) delete_tpl = ("DELETE FROM permission " "WHERE permission = '{permission}'") config = Config(file_='alembic.ini', ini_section='alembic') script_directory = ScriptDirectory.from_config(config) upgrade = ops.UpgradeOps( [ ops.ExecuteSQLOp( insert_tpl.format(uuid=str(uuid.uuid4()), service_name=service_name, permission=permission) ) for permission in perms['to_insert'] ] + [ ops.ExecuteSQLOp(update_tpl.format(is_deleted='false', uuid=p_uuid)) for p_uuid in perms['to_undelete'] ] + [ops.ExecuteSQLOp(update_tpl.format(is_deleted='true', uuid=p_uuid)) for p_uuid in perms['to_delete']] ) downgrade = ops.DowngradeOps( [ops.ExecuteSQLOp(delete_tpl.format(permission=permission)) for permission in perms['to_insert']] + [ ops.ExecuteSQLOp(update_tpl.format(is_deleted='true', uuid=p_uuid)) for p_uuid in perms['to_undelete'] ] + [ ops.ExecuteSQLOp(update_tpl.format(is_deleted='false', uuid=p_uuid)) for p_uuid in perms['to_delete'] ] ) kwargs = { upgrade.upgrade_token: render_python_code(upgrade), downgrade.downgrade_token: render_python_code(downgrade), } script_directory.generate_revision( alembic_rev_id(), 'updating auth permissions', refresh=True, head='head', splice=None, **kwargs )
def test_alt_schema_included_downgrade(self): def include_object(obj, name, type_, reflected, compare_to): if type_ == "table": return name == "t2" else: return True self._update_context(object_filters=include_object, include_schemas=True) uo = ops.UpgradeOps(ops=[]) autogenerate._produce_net_changes(self.autogen_context, uo) diffs = uo.as_diffs() eq_(diffs[0][0], "remove_table") eq_(diffs[0][1].schema, config.test_schema)
def test_double_migrate_table(self): writer = autogenerate.Rewriter() idx_ops = [] @writer.rewrites(ops.ModifyTableOps) def second_table(context, revision, op): return [ op, ops.ModifyTableOps('t2', ops=[ ops.AddColumnOp('t2', sa.Column('x', sa.Integer())) ]) ] @writer.rewrites(ops.AddColumnOp) def add_column(context, revision, op): idx_op = ops.CreateIndexOp('ixt', op.table_name, [op.column.name]) idx_ops.append(idx_op) return [ op, idx_op ] directives = [ ops.MigrationScript( util.rev_id(), ops.UpgradeOps(ops=[ ops.ModifyTableOps('t1', ops=[ ops.AddColumnOp('t1', sa.Column('x', sa.Integer())) ]) ]), ops.DowngradeOps(ops=[]), ) ] ctx, rev = mock.Mock(), mock.Mock() writer(ctx, rev, directives) eq_( [d.table_name for d in directives[0].upgrade_ops.ops], ['t1', 't2'] ) is_( directives[0].upgrade_ops.ops[0].ops[1], idx_ops[0] ) is_( directives[0].upgrade_ops.ops[1].ops[1], idx_ops[1] )
def test_diffs_order(self): """ Added in order to test that child tables(tables with FKs) are generated before their parent tables """ ctx = self.autogen_context uo = ops.UpgradeOps(ops=[]) autogenerate._produce_net_changes(ctx, uo) diffs = uo.as_diffs() eq_(diffs[0][0], 'add_table') eq_(diffs[0][1].name, "parent") eq_(diffs[1][0], 'add_table') eq_(diffs[1][1].name, "child")
def test_variant_no_issue(self): uo = ops.UpgradeOps(ops=[]) autogenerate._produce_net_changes(self.autogen_context, uo) diffs = uo.as_diffs() eq_(diffs, [])
def test_multiple_passes_with_mutations(self): writer1 = autogenerate.Rewriter() @writer1.rewrites(ops.CreateTableOp) def rewrite_alter_column(context, revision, op): op.table_name += "_pass" return op directives = [ ops.MigrationScript( util.rev_id(), ops.UpgradeOps(ops=[ ops.CreateTableOp( "test_table", [sa.Column("id", sa.Integer(), primary_key=True)], ) ]), ops.DowngradeOps(ops=[]), ) ] ctx, rev = mock.Mock(), mock.Mock() writer1(ctx, rev, directives) directives[0].upgrade_ops_list.extend([ ops.UpgradeOps(ops=[ ops.CreateTableOp( "another_test_table", [sa.Column("id", sa.Integer(), primary_key=True)], ) ]), ops.UpgradeOps(ops=[ ops.CreateTableOp( "third_test_table", [sa.Column("id", sa.Integer(), primary_key=True)], ) ]), ]) writer1(ctx, rev, directives) eq_( autogenerate.render_python_code(directives[0].upgrade_ops_list[0]), "# ### commands auto generated by Alembic - please adjust! ###\n" " op.create_table('test_table_pass',\n" " sa.Column('id', sa.Integer(), nullable=False),\n" " sa.PrimaryKeyConstraint('id')\n" " )\n" " # ### end Alembic commands ###", ) eq_( autogenerate.render_python_code(directives[0].upgrade_ops_list[1]), "# ### commands auto generated by Alembic - please adjust! ###\n" " op.create_table('another_test_table_pass',\n" " sa.Column('id', sa.Integer(), nullable=False),\n" " sa.PrimaryKeyConstraint('id')\n" " )\n" " # ### end Alembic commands ###", ) eq_( autogenerate.render_python_code(directives[0].upgrade_ops_list[2]), "# ### commands auto generated by Alembic - please adjust! ###\n" " op.create_table('third_test_table_pass',\n" " sa.Column('id', sa.Integer(), nullable=False),\n" " sa.PrimaryKeyConstraint('id')\n" " )\n" " # ### end Alembic commands ###", )
def test_alembic_render_bigid_function_ops(): upgrade_code = render_python_code(ops.UpgradeOps(ops=[CreateNextBigIdFunctionOp()])) downgrade_code = render_python_code(ops.DowngradeOps(ops=[DropNextBigIdFunctionOp()])) assert 'op.create_nextbigid_function()' in upgrade_code assert 'op.drop_nextbigid_function()' in downgrade_code
def test_autogen_process_directives(self, get_version_branch_path): get_version_branch_path.side_effect = lambda cfg, release, branch: ( "/foo/expand" if branch == 'expand' else "/foo/contract") migration_script = alembic_ops.MigrationScript( 'eced083f5df', # these directives will be split into separate # expand/contract scripts alembic_ops.UpgradeOps(ops=[ alembic_ops.CreateTableOp('organization', [ sa.Column('id', sa.Integer(), primary_key=True), sa.Column('name', sa.String(50), nullable=False) ]), alembic_ops.ModifyTableOps( 'user', ops=[ alembic_ops.AddColumnOp( 'user', sa.Column('organization_id', sa.Integer())), alembic_ops.CreateForeignKeyOp( 'org_fk', 'user', 'organization', ['organization_id'], ['id']), alembic_ops.DropConstraintOp('user', 'uq_user_org'), alembic_ops.DropColumnOp('user', 'organization_name') ]) ]), # these will be discarded alembic_ops.DowngradeOps(ops=[ alembic_ops.AddColumnOp( 'user', sa.Column( 'organization_name', sa.String(50), nullable=True)), alembic_ops.CreateUniqueConstraintOp( 'uq_user_org', 'user', ['user_name', 'organization_name']), alembic_ops.ModifyTableOps( 'user', ops=[ alembic_ops.DropConstraintOp('org_fk', 'user'), alembic_ops.DropColumnOp('user', 'organization_id') ]), alembic_ops.DropTableOp('organization') ]), message='create the organization table and ' 'replace user.organization_name') directives = [migration_script] autogen.process_revision_directives(mock.Mock(), mock.Mock(), directives) expand = directives[0] contract = directives[1] self.assertEqual("/foo/expand", expand.version_path) self.assertEqual("/foo/contract", contract.version_path) self.assertTrue(expand.downgrade_ops.is_empty()) self.assertTrue(contract.downgrade_ops.is_empty()) self.assertEqual( textwrap.dedent( """\ ### commands auto generated by Alembic - please adjust! ### op.create_table('organization', sa.Column('id', sa.Integer(), nullable=False), sa.Column('name', sa.String(length=50), nullable=False), sa.PrimaryKeyConstraint('id') ) op.add_column('user', """ """sa.Column('organization_id', sa.Integer(), nullable=True)) op.create_foreign_key('org_fk', 'user', """ """'organization', ['organization_id'], ['id']) ### end Alembic commands ###"""), alembic_ag_api.render_python_code(expand.upgrade_ops)) self.assertEqual( textwrap.dedent("""\ ### commands auto generated by Alembic - please adjust! ### op.drop_constraint('user', 'uq_user_org', type_=None) op.drop_column('user', 'organization_name') ### end Alembic commands ###"""), alembic_ag_api.render_python_code(contract.upgrade_ops))
def test_no_version_table(self): ctx = self.autogen_context uo = ops.UpgradeOps(ops=[]) autogenerate._produce_net_changes(ctx, uo) eq_(uo.as_diffs(), [])
def test_dont_add_system(self): uo = ops.UpgradeOps(ops=[]) autogenerate._produce_net_changes(self.autogen_context, uo) diffs = uo.as_diffs() eq_(diffs, [])
def test_no_change(self): uo = ops.UpgradeOps(ops=[]) ctx = self.autogen_context autogenerate._produce_net_changes(ctx, uo) diffs = uo.as_diffs() eq_(diffs, [])