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

0

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

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,

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

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

Теги:
mariadb
foreign-keys

1 ответ

1
Лучший ответ

Ваша проблема в том, что вы явно не называете свои ограничения. Это оставляет каждую базу данных, чтобы выбрать имя для вас. Хитрость заключается в том, чтобы явно указывать ограничения внешнего ключа при создании реальных таблиц как в 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, что, вероятно, означает написание хранимой процедуры.

  • 0
    Хорошо, я буду использовать это в будущем. Но могу ли я как-то решить сложившуюся ситуацию?
  • 0
    Это может быть не так просто. Возможно, вам придется запросить одну из таблиц информационной схемы, чтобы найти фактическое имя ограничения, а затем отбросить его. Но это займет динамический SQL.
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню