Написание миграций с внешними ключами в SeqelizeJS
Фон
Я строю проект с SequelizeJS, популярный ORM для NodeJS. При разработке схемы появляются два вида тактики:
- создайте код модели и используйте.функция sync () для автоматического создания таблиц для ваших моделей.
- создать код модели и написать руководство по миграции используя QueryInterface и сайт umzug.
Я понимаю, что #1 лучше для быстрого прототипирования, но что #2-Лучшая практика для проектов, которые, как ожидается, будут повторяться с течением времени, когда производственные данные должны быть в состоянии пережить миграции.
этот вопрос относится к тактике #2.
вопрос(ы)
мои таблицы имеют связи, которые должны быть отражены через внешние ключи.
Как я создание таблиц с отношениями внешнего ключа друг с другом через Sequelize QueryInterface?
какие столбцы и вспомогательные таблицы, необходимые для sequelize? Например, кажется, что ожидаются определенные столбцы, такие как createdAt или updatedAt.
2 ответов
как создать таблицы с отношениями внешнего ключа друг с другом через Sequelize QueryInterface?
на .createTable()
метод принимает в словаре столбцов. Вы можете увидеть список допустимых атрибутов в документация .define()
, а именно по [attributes.column.*]
строки в таблице params.
создать атрибут с внешним ключом отношения, Используйте "ссылки" и "referencesKey" поля:
например, следующее создаст users
таблица, и user_emails
таблица, которая ссылается на таблицу пользователей.
queryInterface.createTable('users', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
}
}).then(function() {
queryInterface.createTable('user_emails', {
userId: {
type: Sequelize.INTEGER,
references: { model: 'users', key: 'id' }
}
})
});
какие столбцы и вспомогательные таблицы, необходимые для sequelize? Например, кажется, что ожидаются определенные столбцы, такие как createdAt или updatedAt.
похоже, что стандартная модель будет ожидать id
, updatedAt
и createdAt
столбец для каждой таблицы.
queryInterface.createTable('users', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
createdAt: {
type: Sequelize.DATE
},
updatedAt: {
type: Sequelize.DATE
}
}
если вы имейте paranoid: true set на вашей модели, вам также понадобится deletedAt
метки.
Я хочу предложить еще один более ручная альтернатива потому что при использовании ручных миграций и queryInterface я столкнулся со следующей проблемой: у меня было 2 файла в папке миграции, как так
migrations/create-project.js
migrations/create-projectType.js
, потому что project
у колонки projectTypeId
это ссылка projectType
, который еще не был создан из-за порядка файлов, и это вызывало ошибку.
я решил это, добавив ограничение внешнего ключа после создания обеих таблиц. В моем случае я решил написать это внутри create-projectType.js
:
queryInterface.createTable('project_type', {
// table attributes ...
})
.then(() => queryInterface.addConstraint('project', ['projectTypeId'], {
type: 'FOREIGN KEY',
name: 'FK_projectType_project', // useful if using queryInterface.removeConstraint
references: {
table: 'project_type',
field: 'id',
},
onDelete: 'no action',
onUpdate: 'no action',
}))