Как добавить столбец в Sequelize существующей модели?

Я добавил модель и файл миграции с помощью этой команды

node_modules/.bin/sequelize model:generate --name User --attributes firstName:string,lastName:string,email:string

Теперь я хотел добавить еще несколько полей, таких как пол и возраст, в существующую таблицу (модель). Я изменил модель вручную и запускаю эту команду

node_modules/.bin/sequelize db:migrate

Но он отвечает, что "Миграции не были выполнены, схема базы данных уже была обновлена".

user.js

'use strict';
module.exports = (sequelize, DataTypes) => {
  var User = sequelize.define('User', {
    firstName: DataTypes.STRING,
    lastName: DataTypes.STRING,
    email: DataTypes.STRING
  }, {});
  User.associate = function(models) {
    // associations can be defined here
  };
  return User;
};

Заранее спасибо:)

6 ответов

Решение

Ответ Суветана правильный, но во фрагменте кода миграции есть небольшая ошибка. Миграции Sequelize ожидают возврата обещания, что отмечено в комментарии в сгенерированном каркасе миграции:

Add altering commands here.
Return a promise to correctly handle asynchronicity.

Example:
return queryInterface.createTable('users', { id: Sequelize.INTEGER });

Таким образом, возвращение массива обещаний может привести к неожиданным результатам, поскольку нет гарантии, что все обещания будут решены до перехода к следующей миграции. Для большинства операций вы вряд ли столкнетесь с какими-либо проблемами, так как большинство вещей завершится до того, как Sequelize закроет процесс. Но я думаю, что лучше быть в безопасности, чем сожалеть, когда дело доходит до миграции баз данных. Вы все еще можете использовать массив обещаний; вам просто нужно обернуть его в Promise.all вызов.

Пример Suvethan, но с Promise.all:

module.exports = {
  up: function (queryInterface, Sequelize) {
    return Promise.all([
      queryInterface.addColumn(
        'Users',
        'gender',
         Sequelize.STRING
       ),
      queryInterface.addColumn(
        'Users',
        'age',
        Sequelize.STRING
      )
    ]);
  },

  down: function (queryInterface, Sequelize) {
    // logic for reverting the changes
  }
};

Чтобы добавить новые поля в таблицу, мы должны использовать скелет миграции, как показано ниже.

sequelize migration:create --name Users

Откройте файл миграции и добавьте следующие коды

module.exports = {
  up: function (queryInterface, Sequelize) {
    return [ queryInterface.addColumn(
              'Users',
              'gender',
               Sequelize.STRING
             ),
            queryInterface.addColumn(
             'Users',
             'age',
             Sequelize.STRING
          )];
  },

  down: function (queryInterface, Sequelize) {
    // logic for reverting the changes
  }
};

Тогда просто запустите миграцию

node_modules/.bin/sequelize db:migrate

Примечание. Переданный объект queryInterface можно использовать для изменения базы данных. Объект Sequelize хранит доступные типы данных, такие как STRING или INTEGER.

Полный список методов в интерфейсе запросов

Я надеюсь, что это поможет вам. Если у вас есть какие-либо проблемы, дайте мне знать.

В вашей инициализации продолжения добавьте alter значение true и добавьте столбец или ассоциацию в существующий файл модели.

      db.sequelize.sync({ force: false, alter: true })

Ты можешь просто сделатьnpx sequelize-cli db:migrate:undoа затем вы можете пойти и изменить в файле миграции все, что захотите, если вы хотите добавить новые атрибуты или если вы хотите добавить свойство, а затем снова сделатьnpx sequelize-cli db:migrateэто будет работать

В дополнение к ответу @Suvethan Nantha, который, кстати, мне только что помог, убедитесь, что вы заключили запросы в Promise.all, т.е. return**Promise.all**([queryInterface.addColumn(...)])так что он вернет обещание, следовательно, может возникнуть ошибка. Ура!

создайте миграцию файлов с помощью этой команды:

      npx sequelize-cli migration:generate --name add_column_name_to_tablename

и вы можете просто использовать это при миграции файлов:

      module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.addColumn('users', 'new_column', {
      type: Sequelize.STRING,
      allowNull: false,
      defaultValue: ''
    });

    // Menempatkan kolom baru setelah kolom email
    await queryInterface.sequelize.query('ALTER TABLE "users" ADD COLUMN "new_column" AFTER "email";');
  },

  down: async (queryInterface, Sequelize) => {
    await queryInterface.removeColumn('users', 'new_column');
  }
};
Другие вопросы по тегам