Подтвердить что ты не робот

Написание миграции с использованием внешних ключей с использованием SequelizeJS

Фон

Я строю проект с SequelizeJS, популярной ORM для NodeJS. При разработке схемы, кажется, есть две тактики:

  1. Создайте код модели и используйте функцию.sync() для автоматического создания таблиц для ваших моделей.
  2. Создайте код модели и напишите миграции вручную, используя QueryInterface и umzug.

Насколько я понимаю, # 1 лучше для быстрого создания прототипов, но что # 2 - это лучшая практика для проектов, которые, как ожидается, будут развиваться со временем и где производственные данные должны быть в состоянии пережить миграции.

Этот вопрос относится к тактике № 2.

Вопросы)

Мои таблицы имеют отношения, которые должны быть отражены через внешние ключи.

  • Как мне создать таблицы с отношениями внешнего ключа друг с другом через Sequelize QueryInterface?

  • Какие столбцы и вспомогательные таблицы требуются Sequelize? Например, кажется, что ожидаются определенные столбцы, такие как созданный или обновленный.

4b9b3361

Ответ 1

Как мне создать таблицы с отношениями внешнего ключа друг с другом через Sequelize QueryInterface?

Метод .createTable() принимает словарь столбцов. Вы можете увидеть список допустимых атрибутов в документации для .define(), в частности, посмотрев строки [attributes.column.*] В таблице параметров.

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

Например, следующее создаст таблицу 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? Например, кажется, что ожидаются определенные столбцы, такие как созданный или обновленный.

Похоже, что стандартная модель будет ожидать 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, вам также понадобится deletedAt метку времени deletedAt.

Ответ 2

Я хочу предложить другую более ручную альтернативу, потому что при использовании ручных миграций и 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',
}))