"""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