Написание миграций с внешними ключами в SeqelizeJS

Фон

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

  1. создайте код модели и используйте.функция sync () для автоматического создания таблиц для ваших моделей.
  2. создать код модели и написать руководство по миграции используя 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',
}))