Fix foreign key and primary key errors in db scripts
Starting from 10.1.x of MariaDB and 5.6 of MySQL, they not allow changes to primary key and foreign key columns after the definitions creation. This breaks db alembic scripts with IntegrityError constraints. Fix db scripts to drop the foreign key constraint and add them back once the definitions are modified in existing schemas. Change-Id: I4a4faa1e6d0aafc26f2a56986f83c4c4f0cfc763 Closes-Bug: #1594807
This commit is contained in:
parent
5b5cd503f6
commit
625b7e707c
|
@ -13,7 +13,9 @@
|
|||
# under the License.
|
||||
|
||||
from alembic import op
|
||||
import contextlib
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.engine import reflection
|
||||
|
||||
|
||||
def alter_enum(table, column, enum_type, nullable):
|
||||
|
@ -35,3 +37,38 @@ def alter_enum(table, column, enum_type, nullable):
|
|||
else:
|
||||
op.alter_column(table, column, type_=enum_type,
|
||||
existing_nullable=nullable)
|
||||
|
||||
|
||||
def create_foreign_key_constraint(table_name, fk_constraints):
|
||||
for fk in fk_constraints:
|
||||
op.create_foreign_key(
|
||||
constraint_name=fk['name'],
|
||||
source_table=table_name,
|
||||
referent_table=fk['referred_table'],
|
||||
local_cols=fk['constrained_columns'],
|
||||
remote_cols=fk['referred_columns'],
|
||||
ondelete=fk['options'].get('ondelete')
|
||||
)
|
||||
|
||||
|
||||
def drop_foreign_key_constraint(table_name, fk_constraints):
|
||||
for fk in fk_constraints:
|
||||
op.drop_constraint(
|
||||
constraint_name=fk['name'],
|
||||
table_name=table_name,
|
||||
type_='foreignkey'
|
||||
)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def modify_foreign_keys_constraint(table_names):
|
||||
inspector = reflection.Inspector.from_engine(op.get_bind())
|
||||
try:
|
||||
for table in table_names:
|
||||
fk_constraints = inspector.get_foreign_keys(table)
|
||||
drop_foreign_key_constraint(table, fk_constraints)
|
||||
yield
|
||||
finally:
|
||||
for table in table_names:
|
||||
fk_constraints = inspector.get_foreign_keys(table)
|
||||
create_foreign_key_constraint(table, fk_constraints)
|
||||
|
|
|
@ -27,17 +27,19 @@ down_revision = '12a57080b277'
|
|||
|
||||
from alembic import op
|
||||
from sqlalchemy.dialects import mysql
|
||||
from tacker.db import migration
|
||||
|
||||
|
||||
def upgrade(active_plugins=None, options=None):
|
||||
# commands auto generated by Alembic - please adjust! #
|
||||
op.alter_column(u'deviceattributes', 'device_id',
|
||||
existing_type=mysql.VARCHAR(length=255),
|
||||
nullable=False)
|
||||
op.alter_column(u'devices', 'status',
|
||||
existing_type=mysql.VARCHAR(length=255),
|
||||
nullable=False)
|
||||
# end Alembic commands #
|
||||
fk_constraint = ('deviceattributes', )
|
||||
with migration.modify_foreign_keys_constraint(fk_constraint):
|
||||
op.alter_column(u'deviceattributes', 'device_id',
|
||||
existing_type=mysql.VARCHAR(length=255),
|
||||
nullable=False)
|
||||
op.alter_column(u'devices', 'status', existing_type=mysql.VARCHAR(
|
||||
length=255), nullable=False)
|
||||
# end Alembic commands #s
|
||||
|
||||
|
||||
def downgrade(active_plugins=None, options=None):
|
||||
|
|
|
@ -28,28 +28,35 @@ down_revision = 'acf941e54075'
|
|||
|
||||
from alembic import op
|
||||
|
||||
from tacker.db import migration
|
||||
from tacker.db import types
|
||||
|
||||
FK_MAP = {'vims': ('vimauths', 'devices'), 'devices': ('deviceattributes',
|
||||
'proxymgmtports'), 'devicetemplates': ('devices', 'servicetypes',
|
||||
'devicetemplateattributes')}
|
||||
|
||||
|
||||
def upgrade(active_plugins=None, options=None):
|
||||
for table in ['vims', 'vimauths', 'devices', 'deviceattributes',
|
||||
|
||||
pk_id_tables = ('vims', 'vimauths', 'devices', 'deviceattributes',
|
||||
'servicetypes', 'devicetemplates',
|
||||
'devicetemplateattributes']:
|
||||
op.alter_column(table,
|
||||
'id',
|
||||
type_=types.Uuid)
|
||||
'devicetemplateattributes')
|
||||
for table in pk_id_tables:
|
||||
with migration.modify_foreign_keys_constraint(FK_MAP.get(table, [])):
|
||||
op.alter_column(table, 'id', type_=types.Uuid)
|
||||
|
||||
for table in ['devices', 'servicetypes', 'devicetemplateattributes']:
|
||||
op.alter_column(table,
|
||||
'template_id',
|
||||
type_=types.Uuid)
|
||||
fk_template_id_tables = ('devices', 'servicetypes',
|
||||
'devicetemplateattributes')
|
||||
for table in fk_template_id_tables:
|
||||
with migration.modify_foreign_keys_constraint(fk_template_id_tables):
|
||||
op.alter_column(table, 'template_id', type_=types.Uuid)
|
||||
|
||||
for table in ['devices', 'vimauths']:
|
||||
op.alter_column(table,
|
||||
'vim_id',
|
||||
type_=types.Uuid)
|
||||
fk_vim_id_tables = ('devices', 'vimauths')
|
||||
for table in fk_vim_id_tables:
|
||||
with migration.modify_foreign_keys_constraint(fk_vim_id_tables):
|
||||
op.alter_column(table, 'vim_id', type_=types.Uuid)
|
||||
|
||||
for table in ['deviceattributes', 'proxymgmtports']:
|
||||
op.alter_column(table,
|
||||
'device_id',
|
||||
type_=types.Uuid)
|
||||
fk_device_id_tables = ('deviceattributes', 'proxymgmtports')
|
||||
for table in fk_device_id_tables:
|
||||
with migration.modify_foreign_keys_constraint(fk_device_id_tables):
|
||||
op.alter_column(table, 'device_id', type_=types.Uuid)
|
||||
|
|
Loading…
Reference in New Issue