Сегодняшняя заметка — узнать, как удалить или добавить внешний ключ в 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
ссылалось на это поле.
Давайте узнаем, как мы можем добавить столбец и изменить ограничение внешнего ключа внутри таблицы.
- Добавить новый столбец
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 параметра будут такими:
- table
— categories
(таблица базы данных)
- key
— catId
(имя столбца, которое мы добавляем)
- 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
.
- tableName
— sub_categories
(имя таблицы базы данных)
- constraintName
— sub_categories_ibfk_1
(имя ограничения из таблицы sub_categories
)
- options
— Объект, содержащий необязательные сведения (например, transaction
)
Метод addConstraint()
принимает 2 параметра: tableName
и options
.
- tableName
— sub_categories
(имя таблицы базы данных)
- options
— объект, содержащий необязательные сведения (такие как ограничение type
, fields
, name
и т. д.)
ПРИМЕЧАНИЕ. Обратите внимание, что у нас есть
catId
какfield
подreferences
.
Если мы успешно запустим файл миграции, мы увидим, что поле ссылки изменилось на catId
.
Ну вот! Надеюсь, вам понравилась сегодняшняя заметка.
Недавно я завел свой личный блог, в котором есть полезная информация о различных языках, фреймворках и библиотеках, поэтому обязательно загляните на danielim.blog.
Спасибо за прочтение. Если у вас есть мысли по этому поводу, обязательно оставьте комментарий. Кроме того, если вы нашли эту статью полезной, дайте мне несколько аплодисментов.