Пример #1
0
    def test_drop_unique_constraint_in_sqlite_fk_recreate(self):
        if "sqlite" in self.engines:
            engine = self.engines["sqlite"]
            meta = MetaData()
            meta.bind = engine
            parent_table_name = "test_drop_unique_constraint_in_sqlite_fk_" "recreate_parent_table"
            parent_table = Table(
                parent_table_name, meta, Column("id", Integer, primary_key=True), Column("foo", Integer)
            )
            parent_table.create()
            table_name = "test_drop_unique_constraint_in_sqlite_fk_recreate"
            table = Table(
                table_name,
                meta,
                Column("id", Integer, primary_key=True),
                Column("baz", Integer),
                Column("bar", Integer, ForeignKey(parent_table_name + ".id")),
                UniqueConstraint("baz", name="constr1"),
            )
            table.create()
            utils.drop_unique_constraint(engine, table_name, "constr1", "baz")

            insp = reflection.Inspector.from_engine(engine)
            f_keys = insp.get_foreign_keys(table_name)
            self.assertEqual(len(f_keys), 1)
            f_key = f_keys[0]
            self.assertEqual(f_key["referred_table"], parent_table_name)
            self.assertEqual(f_key["referred_columns"], ["id"])
            self.assertEqual(f_key["constrained_columns"], ["bar"])
            table.drop()
            parent_table.drop()
Пример #2
0
def downgrade(migrate_engine):
    utils.drop_unique_constraint(migrate_engine, TABLE_NAME, UC_NAME,
                                 *(UC_COLUMNS))
    meta = MetaData(bind=migrate_engine)
    key_pairs = Table(TABLE_NAME, meta, autoload=True)
    Index(OLD_IDX_NAME, key_pairs.c.user_id,
          key_pairs.c.name).create(migrate_engine)
Пример #3
0
    def test_drop_unique_constraint_in_sqlite_fk_recreate(self):
        if 'sqlite' in self.engines:
            engine = self.engines['sqlite']
            meta = MetaData()
            meta.bind = engine
            parent_table_name = ('test_drop_unique_constraint_in_sqlite_fk_'
                                 'recreate_parent_table')
            parent_table = Table(parent_table_name, meta,
                                 Column('id', Integer, primary_key=True),
                                 Column('foo', Integer))
            parent_table.create()
            table_name = 'test_drop_unique_constraint_in_sqlite_fk_recreate'
            table = Table(
                table_name, meta, Column('id', Integer, primary_key=True),
                Column('baz', Integer),
                Column('bar', Integer, ForeignKey(parent_table_name + ".id")),
                UniqueConstraint('baz', name='constr1'))
            table.create()
            utils.drop_unique_constraint(engine, table_name, 'constr1', 'baz')

            insp = reflection.Inspector.from_engine(engine)
            f_keys = insp.get_foreign_keys(table_name)
            self.assertEqual(len(f_keys), 1)
            f_key = f_keys[0]
            self.assertEqual(f_key['referred_table'], parent_table_name)
            self.assertEqual(f_key['referred_columns'], ['id'])
            self.assertEqual(f_key['constrained_columns'], ['bar'])
            table.drop()
            parent_table.drop()
Пример #4
0
    def test_drop_unique_constraint_in_sqlite_fk_recreate(self):
        if 'sqlite' in self.engines:
            engine = self.engines['sqlite']
            meta = MetaData()
            meta.bind = engine
            parent_table_name = ('test_drop_unique_constraint_in_sqlite_fk_'
                                 'recreate_parent_table')
            parent_table = Table(parent_table_name, meta,
                           Column('id', Integer, primary_key=True),
                           Column('foo', Integer))
            parent_table.create()
            table_name = 'test_drop_unique_constraint_in_sqlite_fk_recreate'
            table = Table(table_name, meta,
                          Column('id', Integer, primary_key=True),
                          Column('baz', Integer),
                          Column('bar', Integer,
                                 ForeignKey(parent_table_name + ".id")),
                          UniqueConstraint('baz', name='constr1'))
            table.create()
            utils.drop_unique_constraint(engine, table_name, 'constr1', 'baz')

            insp = reflection.Inspector.from_engine(engine)
            f_keys = insp.get_foreign_keys(table_name)
            self.assertEqual(len(f_keys), 1)
            f_key = f_keys[0]
            self.assertEqual(f_key['referred_table'], parent_table_name)
            self.assertEqual(f_key['referred_columns'], ['id'])
            self.assertEqual(f_key['constrained_columns'], ['bar'])
            table.drop()
            parent_table.drop()
Пример #5
0
def _uc_rename(migrate_engine, upgrade=True):
    UC_DATA.update(UC_SPEC_DB_DATA[migrate_engine.name])

    meta = MetaData(bind=migrate_engine)

    for table in UC_DATA:
        t = Table(table, meta, autoload=True)

        for columns, old_uc_name in UC_DATA[table]:
            new_uc_name = "uniq_{0}0{1}".format(table, "0".join(columns))

            if table in constraint_names and migrate_engine.name == "mysql":
                instances = Table("instances", meta, autoload=True)

                ForeignKeyConstraint(
                    columns=[t.c.instance_uuid],
                    refcolumns=[instances.c.uuid],
                    name=constraint_names[table]
                ).drop(engine=migrate_engine)

            if upgrade:
                old_name, new_name = old_uc_name, new_uc_name
            else:
                old_name, new_name = new_uc_name, old_uc_name

            utils.drop_unique_constraint(migrate_engine, table,
                                         old_name, *(columns))
            UniqueConstraint(*columns, table=t, name=new_name).create()

            if table in constraint_names and migrate_engine.name == "mysql":
                ForeignKeyConstraint(
                    columns=[t.c.instance_uuid],
                    refcolumns=[instances.c.uuid],
                    name=constraint_names[table]
                ).create(engine=migrate_engine)
def downgrade(migrate_engine):
    utils.drop_unique_constraint(migrate_engine, TABLE_NAME, UC_NAME,
                                 *(UC_COLUMNS))
    meta = MetaData(bind=migrate_engine)
    key_pairs = Table(TABLE_NAME, meta, autoload=True)
    Index(OLD_IDX_NAME, key_pairs.c.user_id,
          key_pairs.c.name).create(migrate_engine)
Пример #7
0
def downgrade(migrate_engine):
    meta = MetaData(bind=migrate_engine)
    table = Table(TABLE_NAME, meta, autoload=True)
    utils.drop_unique_constraint(migrate_engine, TABLE_NAME, NEW_NAME,
                                 *COLUMNS)
    uc_old = UniqueConstraint(*COLUMNS, table=table, name=OLD_NAME)
    uc_old.create()
Пример #8
0
    def test_util_drop_unique_constraint_with_not_supported_sqlite_type(self):

        table_name = "__test_tmp_table__"
        uc_name = 'uniq_foo'
        values = [
            {'id': 1, 'a': 3, 'foo': 10},
            {'id': 2, 'a': 2, 'foo': 20},
            {'id': 3, 'a': 1, 'foo': 30}
        ]

        for key, engine in self.engines.items():
            meta = MetaData()
            meta.bind = engine
            test_table = Table(table_name, meta,
                               Column('id', Integer, primary_key=True,
                                      nullable=False),
                               Column('a', Integer),
                               Column('foo', CustomType, default=0),
                               UniqueConstraint('a', name='uniq_a'),
                               UniqueConstraint('foo', name=uc_name))
            test_table.create()

            engine.execute(test_table.insert(), values)
            if key == "sqlite":
                warnings.simplefilter("ignore", SAWarning)
                # NOTE(boris-42): Missing info about column `foo` that has
                #                 unsupported type CustomType.
                self.assertRaises(exception.NovaException,
                                  utils.drop_unique_constraint,
                                  engine, table_name, uc_name, 'foo')

                # NOTE(boris-42): Wrong type of foo instance. it should be
                #                 instance of sqlalchemy.Column.
                self.assertRaises(exception.NovaException,
                                  utils.drop_unique_constraint,
                                  engine, table_name, uc_name, 'foo',
                                  foo=Integer())

            foo = Column('foo', CustomType, default=0)
            utils.drop_unique_constraint(engine, table_name, uc_name, 'foo',
                                         foo=foo)

            s = test_table.select().order_by(test_table.c.id)
            rows = engine.execute(s).fetchall()

            for i in xrange(0, len(values)):
                v = values[i]
                self.assertEqual((v['id'], v['a'], v['foo']), rows[i])

            # NOTE(boris-42): Update data about Table from DB.
            meta = MetaData()
            meta.bind = engine
            test_table = Table(table_name, meta, autoload=True)
            constraints = filter(lambda c: c.name == uc_name,
                                 test_table.constraints)
            self.assertEqual(len(constraints), 0)
            self.assertEqual(len(test_table.constraints), 1)
            test_table.drop()
def upgrade(migrate_engine):
    utils.drop_unique_constraint(migrate_engine, TABLE_NAME, OLD_UC_NAME,
                                 OLD_COLUMN)
    meta = MetaData(bind=migrate_engine)
    t = Table(TABLE_NAME, meta, autoload=True)
    if migrate_engine.name == "mysql":
        index = Index(OLD_COLUMN, t.c[OLD_COLUMN], unique=True)
        index.drop()
    uc = UniqueConstraint(*COLUMNS, table=t, name=UC_NAME)
    uc.create()
def upgrade(migrate_engine):
    utils.drop_unique_constraint(migrate_engine, TABLE_NAME, OLD_UC_NAME,
                                 OLD_COLUMN)
    meta = MetaData(bind=migrate_engine)
    t = Table(TABLE_NAME, meta, autoload=True)
    if migrate_engine.name == "mysql":
        index = Index(OLD_COLUMN, t.c[OLD_COLUMN], unique=True)
        index.drop()
    uc = UniqueConstraint(*COLUMNS, table=t, name=UC_NAME)
    uc.create()
def downgrade(migrate_engine):
    utils.drop_unique_constraint(migrate_engine, TABLE_NAME, UC_NAME, *COLUMNS)
    meta = MetaData(bind=migrate_engine)
    t = Table(TABLE_NAME, meta, autoload=True)
    delete_statement = t.delete().where(t.c.deleted != 0)
    migrate_engine.execute(delete_statement)
    uc = UniqueConstraint(OLD_COLUMN, table=t, name=OLD_UC_NAME)
    uc.create()
    if migrate_engine.name == "mysql":
        index = Index(OLD_COLUMN, t.c[OLD_COLUMN], unique=True)
        index.create()
def downgrade(migrate_engine):
    utils.drop_unique_constraint(migrate_engine, TABLE_NAME, UC_NAME, *COLUMNS)
    meta = MetaData(bind=migrate_engine)
    t = Table(TABLE_NAME, meta, autoload=True)
    delete_statement = t.delete().where(t.c.deleted != 0)
    migrate_engine.execute(delete_statement)
    uc = UniqueConstraint(OLD_COLUMN, table=t, name=OLD_UC_NAME)
    uc.create()
    if migrate_engine.name == "mysql":
        index = Index(OLD_COLUMN, t.c[OLD_COLUMN], unique=True)
        index.create()
Пример #13
0
    def test_util_drop_unique_constraint_with_not_supported_sqlite_type(self):
        if "sqlite" not in self.engines:
            self.skipTest("sqlite is not configured")
        engine = self.engines["sqlite"]
        meta = MetaData(bind=engine)

        table_name = "test_util_drop_unique_constraint_with_not_supported" "_sqlite_type"
        uc_name = "uniq_foo"
        values = [{"id": 1, "a": 3, "foo": 10}, {"id": 2, "a": 2, "foo": 20}, {"id": 3, "a": 1, "foo": 30}]

        test_table = Table(
            table_name,
            meta,
            Column("id", Integer, primary_key=True, nullable=False),
            Column("a", Integer),
            Column("foo", CustomType, default=0),
            UniqueConstraint("a", name="uniq_a"),
            UniqueConstraint("foo", name=uc_name),
        )
        test_table.create()

        engine.execute(test_table.insert(), values)
        warnings.simplefilter("ignore", SAWarning)
        # NOTE(boris-42): Missing info about column `foo` that has
        #                 unsupported type CustomType.
        self.assertRaises(exception.NovaException, utils.drop_unique_constraint, engine, table_name, uc_name, "foo")

        # NOTE(boris-42): Wrong type of foo instance. it should be
        #                 instance of sqlalchemy.Column.
        self.assertRaises(
            exception.NovaException, utils.drop_unique_constraint, engine, table_name, uc_name, "foo", foo=Integer()
        )

        foo = Column("foo", CustomType, default=0)
        utils.drop_unique_constraint(engine, table_name, uc_name, "foo", foo=foo)

        s = test_table.select().order_by(test_table.c.id)
        rows = engine.execute(s).fetchall()

        for i in xrange(0, len(values)):
            v = values[i]
            self.assertEqual((v["id"], v["a"], v["foo"]), rows[i])

        # NOTE(boris-42): Update data about Table from DB.
        meta = MetaData(bind=engine)
        test_table = Table(table_name, meta, autoload=True)
        constraints = filter(lambda c: c.name == uc_name, test_table.constraints)
        self.assertEqual(len(constraints), 0)
        self.assertEqual(len(test_table.constraints), 1)
        test_table.drop()
Пример #14
0
    def test_utils_drop_unique_constraint(self):
        table_name = "__test_tmp_table__"
        uc_name = 'uniq_foo'
        values = [{
            'id': 1,
            'a': 3,
            'foo': 10
        }, {
            'id': 2,
            'a': 2,
            'foo': 20
        }, {
            'id': 3,
            'a': 1,
            'foo': 30
        }]
        for key, engine in self.engines.items():
            meta = MetaData()
            meta.bind = engine
            test_table = Table(
                table_name, meta,
                Column('id', Integer, primary_key=True, nullable=False),
                Column('a', Integer), Column('foo', Integer),
                UniqueConstraint('a', name='uniq_a'),
                UniqueConstraint('foo', name=uc_name))
            test_table.create()

            engine.execute(test_table.insert(), values)
            # NOTE(boris-42): This method is generic UC dropper.
            utils.drop_unique_constraint(engine, table_name, uc_name, 'foo')

            s = test_table.select().order_by(test_table.c.id)
            rows = engine.execute(s).fetchall()

            for i in xrange(0, len(values)):
                v = values[i]
                self.assertEqual((v['id'], v['a'], v['foo']), rows[i])

            # NOTE(boris-42): Update data about Table from DB.
            meta = MetaData()
            meta.bind = engine
            test_table = Table(table_name, meta, autoload=True)
            constraints = filter(lambda c: c.name == uc_name,
                                 test_table.constraints)
            self.assertEqual(len(constraints), 0)
            self.assertEqual(len(test_table.constraints), 1)

            test_table.drop()
def downgrade(migrate_engine):
    if migrate_engine.name == 'mysql':
        # NOTE(jhesketh): MySQL Cannot drop index
        # 'uniq_aggregate_metadata0aggregate_id0key0deleted': needed in a
        # foreign key constraint. So we'll remove the fkey constraint on the
        # aggregate_metadata table and add it back after the index is
        # downgraded.
        meta = MetaData(bind=migrate_engine)
        table = Table('aggregate_metadata', meta, autoload=True)
        ref_table = Table('aggregates', meta, autoload=True)
        params = {'columns': [table.c['aggregate_id']],
                  'refcolumns': [ref_table.c['id']],
                  'name': 'aggregate_metadata_ibfk_1'}
        fkey = ForeignKeyConstraint(**params)
        fkey.drop()

    utils.drop_unique_constraint(migrate_engine, TABLE_NAME, UC_NAME, *COLUMNS)

    if migrate_engine.name == 'mysql':
        fkey.create()
Пример #16
0
    def test_utils_drop_unique_constraint(self):
        table_name = "__test_tmp_table__"
        uc_name = 'uniq_foo'
        values = [
            {'id': 1, 'a': 3, 'foo': 10},
            {'id': 2, 'a': 2, 'foo': 20},
            {'id': 3, 'a': 1, 'foo': 30}
        ]
        for key, engine in self.engines.items():
            meta = MetaData()
            meta.bind = engine
            test_table = Table(table_name, meta,
                               Column('id', Integer, primary_key=True,
                                      nullable=False),
                               Column('a', Integer),
                               Column('foo', Integer),
                               UniqueConstraint('a', name='uniq_a'),
                               UniqueConstraint('foo', name=uc_name))
            test_table.create()

            engine.execute(test_table.insert(), values)
            # NOTE(boris-42): This method is generic UC dropper.
            utils.drop_unique_constraint(engine, table_name, uc_name, 'foo')

            s = test_table.select().order_by(test_table.c.id)
            rows = engine.execute(s).fetchall()

            for i in xrange(0, len(values)):
                v = values[i]
                self.assertEqual((v['id'], v['a'], v['foo']), rows[i])

            # NOTE(boris-42): Update data about Table from DB.
            meta = MetaData()
            meta.bind = engine
            test_table = Table(table_name, meta, autoload=True)
            constraints = filter(lambda c: c.name == uc_name,
                                 test_table.constraints)
            self.assertEqual(len(constraints), 0)
            self.assertEqual(len(test_table.constraints), 1)

            test_table.drop()
def _uc_rename(migrate_engine, upgrade=True):
    UC_DATA.update(UC_SPEC_DB_DATA[migrate_engine.name])

    meta = MetaData(bind=migrate_engine)

    for table in UC_DATA:
        t = Table(table, meta, autoload=True)

        for columns, old_uc_name in UC_DATA[table]:
            new_uc_name = "uniq_{0}0{1}".format(table, "0".join(columns))

            if table in constraint_names and migrate_engine.name == "mysql":
                instances = Table("instances", meta, autoload=True)

                ForeignKeyConstraint(
                    columns=[t.c.instance_uuid],
                    refcolumns=[instances.c.uuid],
                    name=constraint_names[table]
                ).drop(engine=migrate_engine)

            if upgrade:
                old_name, new_name = old_uc_name, new_uc_name
            else:
                old_name, new_name = new_uc_name, old_uc_name

            utils.drop_unique_constraint(migrate_engine, table,
                                         old_name, *(columns))
            if (new_name != 'virtual_interfaces_instance_uuid_fkey' or
                    migrate_engine.name != "mysql"):
                # NOTE(jhesketh): The virtual_interfaces_instance_uuid_fkey
                # key always existed in the table, we don't need to create
                # a unique constraint. See bug/1207344
                UniqueConstraint(*columns, table=t, name=new_name).create()

            if table in constraint_names and migrate_engine.name == "mysql":
                ForeignKeyConstraint(
                    columns=[t.c.instance_uuid],
                    refcolumns=[instances.c.uuid],
                    name=constraint_names[table]
                ).create(engine=migrate_engine)
def downgrade(migrate_engine):
    if migrate_engine.name == 'mysql':
        # NOTE(jhesketh): MySQL Cannot drop index
        # 'uniq_aggregate_metadata0aggregate_id0key0deleted': needed in a
        # foreign key constraint. So we'll remove the fkey constraint on the
        # aggregate_metadata table and add it back after the index is
        # downgraded.
        meta = MetaData(bind=migrate_engine)
        table = Table('aggregate_metadata', meta, autoload=True)
        ref_table = Table('aggregates', meta, autoload=True)
        params = {
            'columns': [table.c['aggregate_id']],
            'refcolumns': [ref_table.c['id']],
            'name': 'aggregate_metadata_ibfk_1'
        }
        fkey = ForeignKeyConstraint(**params)
        fkey.drop()

    utils.drop_unique_constraint(migrate_engine, TABLE_NAME, UC_NAME, *COLUMNS)

    if migrate_engine.name == 'mysql':
        fkey.create()
Пример #19
0
    def test_utils_drop_unique_constraint(self):
        table_name = "test_utils_drop_unique_constraint"
        uc_name = "uniq_foo"
        values = [{"id": 1, "a": 3, "foo": 10}, {"id": 2, "a": 2, "foo": 20}, {"id": 3, "a": 1, "foo": 30}]
        for key, engine in self.engines.items():
            meta = MetaData()
            meta.bind = engine
            test_table = Table(
                table_name,
                meta,
                Column("id", Integer, primary_key=True, nullable=False),
                Column("a", Integer),
                Column("foo", Integer),
                UniqueConstraint("a", name="uniq_a"),
                UniqueConstraint("foo", name=uc_name),
            )
            test_table.create()

            engine.execute(test_table.insert(), values)
            # NOTE(boris-42): This method is generic UC dropper.
            utils.drop_unique_constraint(engine, table_name, uc_name, "foo")

            s = test_table.select().order_by(test_table.c.id)
            rows = engine.execute(s).fetchall()

            for i in xrange(0, len(values)):
                v = values[i]
                self.assertEqual((v["id"], v["a"], v["foo"]), rows[i])

            # NOTE(boris-42): Update data about Table from DB.
            meta = MetaData()
            meta.bind = engine
            test_table = Table(table_name, meta, autoload=True)
            constraints = filter(lambda c: c.name == uc_name, test_table.constraints)
            self.assertEqual(len(constraints), 0)
            self.assertEqual(len(test_table.constraints), 1)

            test_table.drop()
def _uc_rename(migrate_engine, upgrade=True):
    UC_DATA.update(UC_SPEC_DB_DATA[migrate_engine.name])

    meta = MetaData(bind=migrate_engine)

    for table in UC_DATA:
        t = Table(table, meta, autoload=True)

        for columns, old_uc_name in UC_DATA[table]:
            new_uc_name = "uniq_{0}0{1}".format(table, "0".join(columns))

            if table in constraint_names and migrate_engine.name == "mysql":
                instances = Table("instances", meta, autoload=True)

                ForeignKeyConstraint(
                    columns=[t.c.instance_uuid],
                    refcolumns=[instances.c.uuid],
                    name=constraint_names[table]).drop(engine=migrate_engine)

            if upgrade:
                old_name, new_name = old_uc_name, new_uc_name
            else:
                old_name, new_name = new_uc_name, old_uc_name

            utils.drop_unique_constraint(migrate_engine, table, old_name,
                                         *(columns))
            if (new_name != 'virtual_interfaces_instance_uuid_fkey'
                    or migrate_engine.name != "mysql"):
                # NOTE(jhesketh): The virtual_interfaces_instance_uuid_fkey
                # key always existed in the table, we don't need to create
                # a unique constraint. See bug/1207344
                UniqueConstraint(*columns, table=t, name=new_name).create()

            if table in constraint_names and migrate_engine.name == "mysql":
                ForeignKeyConstraint(
                    columns=[t.c.instance_uuid],
                    refcolumns=[instances.c.uuid],
                    name=constraint_names[table]).create(engine=migrate_engine)
Пример #21
0
def downgrade(migrate_engine):
    utils.drop_unique_constraint(migrate_engine, TABLE_NAME, UC_NAME, *COLUMNS)
def _uc_rename(migrate_engine, upgrade=True):
    UC_DATA.update(UC_SPEC_DB_DATA[migrate_engine.name])

    meta = MetaData(bind=migrate_engine)

    for table in UC_DATA:
        t = Table(table, meta, autoload=True)

        for columns, old_uc_name in UC_DATA[table]:
            new_uc_name = "uniq_{0}0{1}".format(table, "0".join(columns))

            if table in constraint_names and migrate_engine.name == "mysql":
                instances = Table("instances", meta, autoload=True)

                if upgrade and (table == 'instance_info_caches'
                                or table == 'virtual_interfaces'):
                    # NOTE(jhesketh): migration 133_folsom.py accidentally
                    #                 changed the name of the FK constraint
                    #                 from instance_info_caches_ibfk_1 to
                    #                 instance_info_caches_instance_uuid_fkey
                    #                 meaning databases who have upgraded from
                    #                 before folsom have the old fkey.
                    #                 We need to make sure all of the fkeys are
                    #                 dropped and then add in the correct fkey
                    #                 regardless. (This also means when 185 is
                    #                 downgraded the user will keep the correct
                    #                 fkey as defined in 133).
                    #                 There also seems to be a case where both
                    #                 versions of the fkey are present in a
                    #                 database so we check for each.
                    #                 Similarly on table virtual_interfaces it
                    #                 is possible to get into a state of having
                    #                 both virtual_interfaces_ibfk_1 and
                    #                 virtual_interfaces_instance_uuid_fkey
                    #                 present in the virtual_interfaces table.
                    for index_name in \
                            ['instance_info_caches_ibfk_1',
                             'instance_info_caches_instance_uuid_fkey',
                             'virtual_interfaces_ibfk_1',
                             'virtual_interfaces_instance_uuid_fkey']:
                        if index_name in [fk.name for fk in t.foreign_keys]:
                            ForeignKeyConstraint(
                                columns=[t.c.instance_uuid],
                                refcolumns=[instances.c.uuid],
                                name=index_name).drop(engine=migrate_engine)
                else:
                    ForeignKeyConstraint(columns=[t.c.instance_uuid],
                                         refcolumns=[instances.c.uuid],
                                         name=constraint_names[table]).drop(
                                             engine=migrate_engine)

            if upgrade:
                old_name, new_name = old_uc_name, new_uc_name
            else:
                old_name, new_name = new_uc_name, old_uc_name

            utils.drop_unique_constraint(migrate_engine, table, old_name,
                                         *(columns))
            if (new_name != 'virtual_interfaces_instance_uuid_fkey'
                    or migrate_engine.name != "mysql"):
                # NOTE(jhesketh): The virtual_interfaces_instance_uuid_fkey
                # key always existed in the table, we don't need to create
                # a unique constraint. See bug/1207344
                UniqueConstraint(*columns, table=t, name=new_name).create()

            if table in constraint_names and migrate_engine.name == "mysql":
                ForeignKeyConstraint(
                    columns=[t.c.instance_uuid],
                    refcolumns=[instances.c.uuid],
                    name=constraint_names[table]).create(engine=migrate_engine)
Пример #23
0
    def test_util_drop_unique_constraint_with_not_supported_sqlite_type(self):
        class CustomType(UserDefinedType):
            """Dummy column type for testing unsupported types."""

            def get_col_spec(self):
                return "CustomType"

        table_name = "__test_tmp_table__"
        uc_name = "uniq_foo"
        values = [{"id": 1, "a": 3, "foo": 10}, {"id": 2, "a": 2, "foo": 20}, {"id": 3, "a": 1, "foo": 30}]

        for key, engine in self.engines.items():
            meta = MetaData()
            meta.bind = engine
            test_table = Table(
                table_name,
                meta,
                Column("id", Integer, primary_key=True, nullable=False),
                Column("a", Integer),
                Column("foo", CustomType, default=0),
                UniqueConstraint("a", name="uniq_a"),
                UniqueConstraint("foo", name=uc_name),
            )
            test_table.create()

            engine.execute(test_table.insert(), values)
            if key == "sqlite":
                warnings.simplefilter("ignore", SAWarning)
                # NOTE(boris-42): Missing info about column `foo` that has
                #                 unsupported type CustomType.
                self.assertRaises(
                    exception.NovaException, utils.drop_unique_constraint, engine, table_name, uc_name, "foo"
                )

                # NOTE(boris-42): Wrong type of foo instance. it should be
                #                 instance of sqlalchemy.Column.
                self.assertRaises(
                    exception.NovaException,
                    utils.drop_unique_constraint,
                    engine,
                    table_name,
                    uc_name,
                    "foo",
                    foo=Integer(),
                )

            foo = Column("foo", CustomType, default=0)
            utils.drop_unique_constraint(engine, table_name, uc_name, "foo", foo=foo)

            s = test_table.select().order_by(test_table.c.id)
            rows = engine.execute(s).fetchall()

            for i in xrange(0, len(values)):
                v = values[i]
                self.assertEqual((v["id"], v["a"], v["foo"]), rows[i])

            # NOTE(boris-42): Update data about Table from DB.
            meta = MetaData()
            meta.bind = engine
            test_table = Table(table_name, meta, autoload=True)
            constraints = filter(lambda c: c.name == uc_name, test_table.constraints)
            self.assertEqual(len(constraints), 0)
            self.assertEqual(len(test_table.constraints), 1)
            test_table.drop()
Пример #24
0
def downgrade(migrate_engine):
    utils.drop_unique_constraint(migrate_engine, TABLE_NAME, UC_NAME, *COLUMNS)
Пример #25
0
    def test_util_drop_unique_constraint_with_not_supported_sqlite_type(self):
        if 'sqlite' not in self.engines:
            self.skipTest('sqlite is not configured')
        engine = self.engines['sqlite']
        meta = MetaData(bind=engine)

        table_name = ("test_util_drop_unique_constraint_with_not_supported"
                      "_sqlite_type")
        uc_name = 'uniq_foo'
        values = [
            {'id': 1, 'a': 3, 'foo': 10},
            {'id': 2, 'a': 2, 'foo': 20},
            {'id': 3, 'a': 1, 'foo': 30}
        ]

        test_table = Table(table_name, meta,
                            Column('id', Integer, primary_key=True,
                                  nullable=False),
                           Column('a', Integer),
                           Column('foo', CustomType, default=0),
                           UniqueConstraint('a', name='uniq_a'),
                           UniqueConstraint('foo', name=uc_name))
        test_table.create()

        engine.execute(test_table.insert(), values)
        warnings.simplefilter("ignore", SAWarning)

        # reflection of custom types has been fixed upstream
        if SA_VERSION < (0, 9, 0):
            # NOTE(boris-42): Missing info about column `foo` that has
            #                 unsupported type CustomType.
            self.assertRaises(exception.NovaException,
                              utils.drop_unique_constraint,
                              engine, table_name, uc_name, 'foo')

            # NOTE(boris-42): Wrong type of foo instance. it should be
            #                 instance of sqlalchemy.Column.
            self.assertRaises(exception.NovaException,
                              utils.drop_unique_constraint,
                              engine, table_name, uc_name, 'foo',
                              foo=Integer())

        foo = Column('foo', CustomType, default=0)
        utils.drop_unique_constraint(engine, table_name, uc_name, 'foo',
                                     foo=foo)

        s = test_table.select().order_by(test_table.c.id)
        rows = engine.execute(s).fetchall()

        for i in xrange(0, len(values)):
            v = values[i]
            self.assertEqual((v['id'], v['a'], v['foo']), rows[i])

        # NOTE(boris-42): Update data about Table from DB.
        meta = MetaData(bind=engine)
        test_table = Table(table_name, meta, autoload=True)
        constraints = filter(lambda c: c.name == uc_name,
                             test_table.constraints)
        self.assertEqual(len(constraints), 0)
        self.assertEqual(len(test_table.constraints), 1)
        test_table.drop()
def downgrade(migrate_engine):
    utils.drop_unique_constraint(migrate_engine, TABLE_NAME, UC_FLAVOR,
                                 *FLAVOR_COLUMNS)
    utils.drop_unique_constraint(migrate_engine, TABLE_NAME, UC_NAME,
                                 *NAME_COLUMNS)
Пример #27
0
def _uc_rename(migrate_engine, upgrade=True):
    UC_DATA.update(UC_SPEC_DB_DATA[migrate_engine.name])

    meta = MetaData(bind=migrate_engine)

    for table in UC_DATA:
        t = Table(table, meta, autoload=True)

        for columns, old_uc_name in UC_DATA[table]:
            new_uc_name = "uniq_{0}0{1}".format(table, "0".join(columns))

            if table in constraint_names and migrate_engine.name == "mysql":
                instances = Table("instances", meta, autoload=True)

                if upgrade and (table == "instance_info_caches" or table == "virtual_interfaces"):
                    # NOTE(jhesketh): migration 133_folsom.py accidentally
                    #                 changed the name of the FK constraint
                    #                 from instance_info_caches_ibfk_1 to
                    #                 instance_info_caches_instance_uuid_fkey
                    #                 meaning databases who have upgraded from
                    #                 before folsom have the old fkey.
                    #                 We need to make sure all of the fkeys are
                    #                 dropped and then add in the correct fkey
                    #                 regardless. (This also means when 185 is
                    #                 downgraded the user will keep the correct
                    #                 fkey as defined in 133).
                    #                 There also seems to be a case where both
                    #                 versions of the fkey are present in a
                    #                 database so we check for each.
                    #                 Similarly on table virtual_interfaces it
                    #                 is possible to get into a state of having
                    #                 both virtual_interfaces_ibfk_1 and
                    #                 virtual_interfaces_instance_uuid_fkey
                    #                 present in the virtual_interfaces table.
                    for index_name in [
                        "instance_info_caches_ibfk_1",
                        "instance_info_caches_instance_uuid_fkey",
                        "virtual_interfaces_ibfk_1",
                        "virtual_interfaces_instance_uuid_fkey",
                    ]:
                        if index_name in [fk.name for fk in t.foreign_keys]:
                            ForeignKeyConstraint(
                                columns=[t.c.instance_uuid], refcolumns=[instances.c.uuid], name=index_name
                            ).drop(engine=migrate_engine)
                else:
                    ForeignKeyConstraint(
                        columns=[t.c.instance_uuid], refcolumns=[instances.c.uuid], name=constraint_names[table]
                    ).drop(engine=migrate_engine)

            if upgrade:
                old_name, new_name = old_uc_name, new_uc_name
            else:
                old_name, new_name = new_uc_name, old_uc_name

            utils.drop_unique_constraint(migrate_engine, table, old_name, *(columns))
            if new_name != "virtual_interfaces_instance_uuid_fkey" or migrate_engine.name != "mysql":
                # NOTE(jhesketh): The virtual_interfaces_instance_uuid_fkey
                # key always existed in the table, we don't need to create
                # a unique constraint. See bug/1207344
                UniqueConstraint(*columns, table=t, name=new_name).create()

            if table in constraint_names and migrate_engine.name == "mysql":
                ForeignKeyConstraint(
                    columns=[t.c.instance_uuid], refcolumns=[instances.c.uuid], name=constraint_names[table]
                ).create(engine=migrate_engine)
Пример #28
0
def downgrade(migrate_engine):
    utils.drop_unique_constraint(migrate_engine, TABLE_NAME, UC_FLAVOR,
                                 *FLAVOR_COLUMNS)
    utils.drop_unique_constraint(migrate_engine, TABLE_NAME, UC_NAME,
                                 *NAME_COLUMNS)
Пример #29
0
    def test_util_drop_unique_constraint_with_not_supported_sqlite_type(self):
        if 'sqlite' not in self.engines:
            self.skipTest('sqlite is not configured')
        engine = self.engines['sqlite']
        meta = MetaData(bind=engine)

        table_name = ("test_util_drop_unique_constraint_with_not_supported"
                      "_sqlite_type")
        uc_name = 'uniq_foo'
        values = [{
            'id': 1,
            'a': 3,
            'foo': 10
        }, {
            'id': 2,
            'a': 2,
            'foo': 20
        }, {
            'id': 3,
            'a': 1,
            'foo': 30
        }]

        test_table = Table(
            table_name, meta,
            Column('id', Integer, primary_key=True, nullable=False),
            Column('a', Integer), Column('foo', CustomType, default=0),
            UniqueConstraint('a', name='uniq_a'),
            UniqueConstraint('foo', name=uc_name))
        test_table.create()

        engine.execute(test_table.insert(), values)
        warnings.simplefilter("ignore", SAWarning)

        # reflection of custom types has been fixed upstream
        if SA_VERSION < (0, 9, 0):
            # NOTE(boris-42): Missing info about column `foo` that has
            #                 unsupported type CustomType.
            self.assertRaises(exception.NovaException,
                              utils.drop_unique_constraint, engine, table_name,
                              uc_name, 'foo')

            # NOTE(boris-42): Wrong type of foo instance. it should be
            #                 instance of sqlalchemy.Column.
            self.assertRaises(exception.NovaException,
                              utils.drop_unique_constraint,
                              engine,
                              table_name,
                              uc_name,
                              'foo',
                              foo=Integer())

        foo = Column('foo', CustomType, default=0)
        utils.drop_unique_constraint(engine,
                                     table_name,
                                     uc_name,
                                     'foo',
                                     foo=foo)

        s = test_table.select().order_by(test_table.c.id)
        rows = engine.execute(s).fetchall()

        for i in xrange(0, len(values)):
            v = values[i]
            self.assertEqual((v['id'], v['a'], v['foo']), rows[i])

        # NOTE(boris-42): Update data about Table from DB.
        meta = MetaData(bind=engine)
        test_table = Table(table_name, meta, autoload=True)
        constraints = filter(lambda c: c.name == uc_name,
                             test_table.constraints)
        self.assertEqual(len(constraints), 0)
        self.assertEqual(len(test_table.constraints), 1)
        test_table.drop()