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()
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)
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()
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()
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): 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()
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 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 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()
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()
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()
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)
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)
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()
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)
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)
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()