Fix all foreign key constraints to use naming convention.

This commit is contained in:
Jake Moshenko 2016-08-18 14:29:53 -04:00
parent ade82910b5
commit d6a396be34

View file

@ -0,0 +1,141 @@
"""Rename all foreign key constraints to have predictable names
Revision ID: 983247d75af3
Revises: 8981dabd329f
Create Date: 2016-08-08 16:33:00.198527
"""
# revision identifiers, used by Alembic.
revision = '983247d75af3'
down_revision = '8981dabd329f'
from alembic import op
from functools import wraps
import sqlalchemy as sa
import logging
logger = logging.getLogger(__name__)
CORRECT_FKC_NAMES = {
# Names that existed according to the constraint in previous migrations
"fk_accesstoken_kind_id_accesstokenkind",
"fk_blobupload_location_id_imagestoragelocation",
"fk_blobupload_repository_id_repository",
"fk_derivedstorageforimage_derivative_id_imagestorage",
"fk_derivedstorageforimage_source_image_id_image",
"fk_imagestoragesignature_kind_id_imagestoragesignaturekind",
"fk_imagestoragesignature_storage_id_imagestorage",
"fk_quayrelease_region_id_quayregion",
"fk_quayrelease_service_id_quayservice",
"fk_repositoryactioncount_repository_id_repository",
"fk_servicekey_approval_id_servicekeyapproval",
"fk_star_repository_id_repository",
"fk_star_user_id_user",
"fk_tagmanifest_tag_id_repositorytag",
"fk_torrentinfo_storage_id_imagestorage",
"fk_userregion_location_id_imagestoragelocation",
"fk_userregion_user_id_user",
# Names that had to be set manually as truncated versions
'fk_derivedstorageforimage_transformation_constraint',
}
def _generate_all_foreign_key_constraint_names():
conn = op.get_bind()
inspector = sa.inspect(conn.engine)
for table_name, fkc_list in inspector.get_sorted_table_and_fkc_names():
for fkc_name in fkc_list:
yield table_name, fkc_name
def _wrap_create_op(create_foreign_key_func, existing_fk_tuple_set):
fk_name_set = set()
@wraps(create_foreign_key_func)
def wrapped(fk_name, table_name, *args, **kwargs):
fk_name_set.add(fk_name)
if (table_name, fk_name) in existing_fk_tuple_set:
logger.debug('Skipping already correct fkc: %s', fk_name)
else:
logger.debug('Creating foreign key constraint: %s', fk_name)
return create_foreign_key_func(op.f(fk_name), table_name, *args, **kwargs)
return wrapped, fk_name_set
def _disable_constraints():
conn = op.get_bind()
if conn.dialect.name == 'mysql':
logger.debug('Setting mysql foreign_key_checks=0')
op.execute('SET FOREIGN_KEY_CHECKS=0')
else:
logger.warning('Unable to disable foreign key checks for dialect: %s', conn.dialect.name)
def upgrade(tables):
existing_fk_tuples = set(_generate_all_foreign_key_constraint_names())
create_fk, new_fk_name_set = _wrap_create_op(op.create_foreign_key, existing_fk_tuples)
_disable_constraints()
create_fk('fk_accesstoken_role_id_role', 'accesstoken', 'role', ['role_id'], ['id'])
create_fk('fk_accesstoken_repository_id_repository', 'accesstoken', 'repository', ['repository_id'], ['id'])
create_fk('fk_emailconfirmation_user_id_user', 'emailconfirmation', 'user', ['user_id'], ['id'])
create_fk('fk_federatedlogin_user_id_user', 'federatedlogin', 'user', ['user_id'], ['id'])
create_fk('fk_federatedlogin_service_id_loginservice', 'federatedlogin', 'loginservice', ['service_id'], ['id'])
create_fk('fk_image_repository_id_repository', 'image', 'repository', ['repository_id'], ['id'])
create_fk('fk_image_storage_id_imagestorage', 'image', 'imagestorage', ['storage_id'], ['id'])
create_fk('fk_imagestorageplacement_location_id_imagestoragelocation', 'imagestorageplacement', 'imagestoragelocation', ['location_id'], ['id'])
create_fk('fk_imagestorageplacement_storage_id_imagestorage', 'imagestorageplacement', 'imagestorage', ['storage_id'], ['id'])
create_fk('fk_logentry_kind_id_logentrykind', 'logentry', 'logentrykind', ['kind_id'], ['id'])
create_fk('fk_notification_target_id_user', 'notification', 'user', ['target_id'], ['id'])
create_fk('fk_notification_kind_id_notificationkind', 'notification', 'notificationkind', ['kind_id'], ['id'])
create_fk('fk_oauthaccesstoken_authorized_user_id_user', 'oauthaccesstoken', 'user', ['authorized_user_id'], ['id'])
create_fk('fk_oauthaccesstoken_application_id_oauthapplication', 'oauthaccesstoken', 'oauthapplication', ['application_id'], ['id'])
create_fk('fk_oauthapplication_organization_id_user', 'oauthapplication', 'user', ['organization_id'], ['id'])
create_fk('fk_oauthauthorizationcode_application_id_oauthapplication', 'oauthauthorizationcode', 'oauthapplication', ['application_id'], ['id'])
create_fk('fk_permissionprototype_delegate_team_id_team', 'permissionprototype', 'team', ['delegate_team_id'], ['id'])
create_fk('fk_permissionprototype_role_id_role', 'permissionprototype', 'role', ['role_id'], ['id'])
create_fk('fk_permissionprototype_delegate_user_id_user', 'permissionprototype', 'user', ['delegate_user_id'], ['id'])
create_fk('fk_permissionprototype_activating_user_id_user', 'permissionprototype', 'user', ['activating_user_id'], ['id'])
create_fk('fk_permissionprototype_org_id_user', 'permissionprototype', 'user', ['org_id'], ['id'])
create_fk('fk_repository_namespace_user_id_user', 'repository', 'user', ['namespace_user_id'], ['id'])
create_fk('fk_repository_visibility_id_visibility', 'repository', 'visibility', ['visibility_id'], ['id'])
create_fk('fk_repositoryauthorizedemail_repository_id_repository', 'repositoryauthorizedemail', 'repository', ['repository_id'], ['id'])
create_fk('fk_repositorybuild_access_token_id_accesstoken', 'repositorybuild', 'accesstoken', ['access_token_id'], ['id'])
create_fk('fk_repositorybuild_pull_robot_id_user', 'repositorybuild', 'user', ['pull_robot_id'], ['id'])
create_fk('fk_repositorybuild_repository_id_repository', 'repositorybuild', 'repository', ['repository_id'], ['id'])
create_fk('fk_repositorybuild_trigger_id_repositorybuildtrigger', 'repositorybuild', 'repositorybuildtrigger', ['trigger_id'], ['id'])
create_fk('fk_repositorybuildtrigger_repository_id_repository', 'repositorybuildtrigger', 'repository', ['repository_id'], ['id'])
create_fk('fk_repositorybuildtrigger_connected_user_id_user', 'repositorybuildtrigger', 'user', ['connected_user_id'], ['id'])
create_fk('fk_repositorybuildtrigger_service_id_buildtriggerservice', 'repositorybuildtrigger', 'buildtriggerservice', ['service_id'], ['id'])
create_fk('fk_repositorybuildtrigger_pull_robot_id_user', 'repositorybuildtrigger', 'user', ['pull_robot_id'], ['id'])
create_fk('fk_repositorybuildtrigger_write_token_id_accesstoken', 'repositorybuildtrigger', 'accesstoken', ['write_token_id'], ['id'])
create_fk('fk_repositorynotification_method_id_externalnotificationmethod', 'repositorynotification', 'externalnotificationmethod', ['method_id'], ['id'])
create_fk('fk_repositorynotification_repository_id_repository', 'repositorynotification', 'repository', ['repository_id'], ['id'])
create_fk('fk_repositorynotification_event_id_externalnotificationevent', 'repositorynotification', 'externalnotificationevent', ['event_id'], ['id'])
create_fk('fk_repositorypermission_role_id_role', 'repositorypermission', 'role', ['role_id'], ['id'])
create_fk('fk_repositorypermission_user_id_user', 'repositorypermission', 'user', ['user_id'], ['id'])
create_fk('fk_repositorypermission_repository_id_repository', 'repositorypermission', 'repository', ['repository_id'], ['id'])
create_fk('fk_repositorypermission_team_id_team', 'repositorypermission', 'team', ['team_id'], ['id'])
create_fk('fk_repositorytag_repository_id_repository', 'repositorytag', 'repository', ['repository_id'], ['id'])
create_fk('fk_repositorytag_image_id_image', 'repositorytag', 'image', ['image_id'], ['id'])
create_fk('fk_team_organization_id_user', 'team', 'user', ['organization_id'], ['id'])
create_fk('fk_team_role_id_teamrole', 'team', 'teamrole', ['role_id'], ['id'])
create_fk('fk_teammember_user_id_user', 'teammember', 'user', ['user_id'], ['id'])
create_fk('fk_teammember_team_id_team', 'teammember', 'team', ['team_id'], ['id'])
create_fk('fk_teammemberinvite_inviter_id_user', 'teammemberinvite', 'user', ['inviter_id'], ['id'])
create_fk('fk_teammemberinvite_team_id_team', 'teammemberinvite', 'team', ['team_id'], ['id'])
create_fk('fk_teammemberinvite_user_id_user', 'teammemberinvite', 'user', ['user_id'], ['id'])
# Drop all of the fk names that aren't correct
final_correct_fk_names = new_fk_name_set | CORRECT_FKC_NAMES
for table_name, fk_name in existing_fk_tuples:
if fk_name not in final_correct_fk_names:
logger.debug("dropping: %s", fk_name)
op.drop_constraint(fk_name, table_name, type_='foreignkey')
def downgrade(tables):
# nah
pass