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",
         ),
     ]
Exemple #2
0
    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])
Exemple #4
0
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)
Exemple #8
0
    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()
Exemple #9
0
    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,
        )
Exemple #10
0
    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')
Exemple #11
0
    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 ###",
        )
Exemple #13
0
 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')])
Exemple #14
0
    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')])
Exemple #16
0
    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
Exemple #17
0
    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 ###",
        )
Exemple #19
0
    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)
Exemple #22
0
    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]
        )
Exemple #23
0
    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))
Exemple #28
0
    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, [])
Exemple #30
0
 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, [])