Sql: невозможно удалить внешний ключ из-за автоматически сгенерированного ограничения - PullRequest
0 голосов
/ 27 марта 2019

У меня есть внешний ключ, который был создан с помощью следующей команды в старой и уже развернутой миграции:

ALTER TABLE `job_template`
  ADD COLUMN `parent_id` BIGINT,
  ADD FOREIGN KEY fk_job_template_parent_id(parent_id) REFERENCES job_template(id) ON DELETE CASCADE;

Теперь я пытаюсь удалить этот внешний ключ с помощью следующей команды:

ALTER TABLE job_template DROP FOREIGN KEY fk_job_template_parent_id;

Проблема в том, что это работает для mariaDB, но не для mySQL, и мне нужна миграция, которая работала бы в обоих случаях

Если я перечислю команду SHOW CREATE TABLE (до удаления внешнего ключа)из обеих сред я получаю следующее:

mariaDB:

 constraint fk_job_template_parent_id foreign key (parent_id) references job_template (id) on delete cascade,

mysql:

 constraint job_template_ibfk_5 foreign key (parent_id) references job_template (id) on delete cascade,

Имена ограничений различны в двух средах, и поэтому я имеюнет способа написать миграцию, которая бы последовательно удаляла этот внешний ключ.

Есть ли способ обойти эту ситуацию?

1 Ответ

1 голос
/ 27 марта 2019

Ваша проблема в том, что вы явно не называете свои ограничения.Это оставляет каждую базу данных, чтобы выбрать имя для вас.Хитрость заключается в том, чтобы явно указывать ограничения внешнего ключа, когда вы создаете фактические таблицы на MySQL и MariaDB:

CREATE TABLE job_template (
    ...,
    parent_id int NOT NULL,
    CONSTRAINT your_constraint FOREIGN KEY fk_name (parent_id)
        REFERENCES job_template(id) ON DELETE CASCADE
);

Но исправление вашей непосредственной ситуации потребует больше работы.Одним из вариантов может быть запрос к таблице информационной схемы для соответствующей таблицы, чтобы узнать действительные имена ограничений:

USE INFORMATION_SCHEMA;

SELECT
   TABLE_NAME,
   COLUMN_NAME,
   CONSTRAINT_NAME,
   REFERENCED_TABLE_NAME,
   REFERENCED_COLUMN_NAME
FROM KEY_COLUMN_USAGE
WHERE
    TABLE_SCHEMA = 'your_db' AND
    TABLE_NAME = 'job_template' AND
    REFERENCED_COLUMN_NAME IS NOT NULL;

Это должно вернуть одну запись для каждого столбца и ограничения.Получив эту информацию, вы сможете запускать текущие операторы alter.

Это достаточно просто сделать с помощью такого инструмента, как Java, или чего-то подобного.Если вы хотите сделать это непосредственно из базы данных, вам потребуется динамический SQL, что, вероятно, означает написание хранимой процедуры.

...