Сегодняшняя заметка — узнать, как удалить или добавить внешний ключ в Sequelize.

Вот итог сегодняшней заметки.

«Чтобы удалить внешний ключ, используйте removeConstraint. Чтобы добавить внешний ключ, используйте addConstraint».

Поскольку потребности бизнеса часто меняются, изменения в базе данных также необходимы.

Допустим, в нашем приложении есть 2 модели — Category и Subcategory.

Это поля, которые в настоящее время есть у каждой модели:

Category:

  • id (автоинкремент)
  • type
  • createdAt
  • updatedAt

Subcategory:

  • id (автоинкремент)
  • type
  • categoryId (ссылка на «id» из категории)
  • createAt
  • updatedAt

Связь между Category и Subcategory равна 1 : N (один ко многим). Каждая категория может иметь множество подкатегорий.

Чтобы привести вам несколько примеров,

Category: Еда
Subcategory: Бакалея, Кофе, Рестораны, Алкоголь
Category: Покупки
Subcategory: Одежда, Книги, Электроника

Они будут храниться в нашей базе данных примерно так:

Category:

Subcategory:

Все отлично, все работает и все довольны.

Но что, если одна из категорий была случайно удалена? Что, если мы хотим провести интеграционное тестирование?

ПРИМЕЧАНИЕ. Хотя некоторые разработчики предпочитают иметь некоторые данные в базе данных перед выполнением интеграционного тестирования, я предпочитаю очистить базу данных.

Поскольку поле id является полем с автоинкрементом, даже если мы вставим ту же категорию типа food, id будет другим (это не будет 5).

Поле categoryId в таблице sub_categories по-прежнему будет иметь значение 5, когда 5 больше не существует в таблице categories.

Чтобы решить эту проблему, мы можем создать еще одно поле catId в таблице categories и сделать так, чтобы categoryId в таблице sub_categories ссылалось на это поле.

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

  1. Добавить новый столбец catId в таблицу categories

Позвольте мне объяснить, что здесь происходит.

Я создал отдельный файл с именем add-catId-column-category-table.js. Это файл миграции, который мы собираемся использовать для внесения изменений в нашу базу данных. В реальной жизни мы никогда не модифицируем таблицы базы данных напрямую из инструмента базы данных (например, PL/SQL Developer или MySQL WorkBench).

Если вы не знакомы с процессом миграции, прочтите эту Официальную документацию Sequelize по миграции.

Я также использую transaction, чтобы сделать наш процесс более безопасным. Если у нас есть 3 задачи, которые нужно выполнить за один transaction, все 3 задачи должны быть выполнены успешно. В противном случае весь процесс откатится и ничего не произойдет. Для получения дополнительной информации вы также можете обратиться к этому Sequelize официальной документации для транзакций.

Внутри функции up у нас есть queryInterface.addColumn(). Метод addColumn() принимает 4 параметра: table, key, attribute и options.
В нашем примере эти 4 параметра будут такими:
- tablecategories (таблица базы данных)
- keycatId (имя столбца, которое мы добавляем)
- attribute — Объект, который указывает детали столбца (например, type, allowNull, unique)
- options — Объект, который содержит необязательные элементы (например, transaction)

ПРИМЕЧАНИЕ. unique: true здесь очень важно. Поскольку у нас не может быть нескольких первичных ключей, нам нужно установить catId на unique. В противном случае мы получим ошибку, когда позже изменим внешний ключ в sub_categories.

Идеальный! Теперь у нас есть новый столбец catId, который мы собираемся связать со столбцом categoryId в таблице sub_categories.

Теперь, когда мы настроили catId, давайте изменим внешний ключ в sub_categories.

Прежде чем мы внесем изменения, вот как на данный момент установлено ограничение.

2. Удалите ограничение и снова добавьте его со столбцом catId.

Опять же, я создал еще один файл миграции change-foreignkey-constraint-sub_categories-table.js.

В MySQL, чтобы изменить ссылку, которую использует внешний ключ, нам нужно изменить ограничение, которое он использует.

К сожалению, мы не можем напрямую изменить ограничение. По этой причине нам нужно сначала удалить ограничение, а затем добавить его снова.

Внутри функции up мы удаляем текущее ограничение sub_categories_ibfk_1, которое ссылается на id из таблицы categories, используя метод removeConstraint().
Затем мы добавляем новое ограничение, используя метод addConstraint(), в таблицу sub_categories.

Метод removeConstraint() принимает 3 параметра: tableName, constraintName и options.
- tableNamesub_categories (имя таблицы базы данных)
- constraintNamesub_categories_ibfk_1 (имя ограничения из таблицы sub_categories)
- options — Объект, содержащий необязательные сведения (например, transaction)

Метод addConstraint() принимает 2 параметра: tableName и options.
- tableNamesub_categories (имя таблицы базы данных)
- options — объект, содержащий необязательные сведения (такие как ограничение type, fields, name и т. д.)

ПРИМЕЧАНИЕ. Обратите внимание, что у нас есть catId как field под references.

Если мы успешно запустим файл миграции, мы увидим, что поле ссылки изменилось на catId.

Ну вот! Надеюсь, вам понравилась сегодняшняя заметка.

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

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