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_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_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 diff_db(self, output_sql=False): migrations = self.get_outstanding_migrations() if output_sql: commented_source_code = render_python_code( migrations.upgrade_ops, alembic_module_prefix='op2.', sqlalchemy_module_prefix="sqlalchemy.") uncommented_source_code = [ i.strip() for i in commented_source_code.split('\n') if not i.strip().startswith('#') ] source_code = '\n'.join(['import sqlalchemy'] + uncommented_source_code) opts = {'as_sql': output_sql, 'target_metadata': metadata} with Operations.context( MigrationContext.configure(connection=Session.connection(), opts=opts)) as op2: exec(source_code, globals(), locals()) return uncommented_source_code else: migrations_required = migrations.upgrade_ops.as_diffs() if migrations_required: pprint.pprint(migrations_required, indent=2, width=20) return migrations_required
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