Как добавить, удалить новые столбцы в Sequelize CLI

Я только начал использовать Sequelize и Sequelize CLI

Поскольку это время разработки, частое добавление и удаление столбцов. Каков наилучший способ добавления нового столбца в существующую модель?

Например, я хочу, чтобы новый столбец был " завершен " для модели Todo. Я добавлю этот столбец в models/todo.js. Следующий шаг?

Я попробовал sequelize db:migrate

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

Ответы

Ответ 1

Если вы используете sequelize-cli, вам нужно сначала создать миграцию. Это просто файл, который сообщает движку, как обновить базу данных и как откатить изменения, если что-то пойдет не так. Вы должны всегда фиксировать этот файл в своем хранилище

$ sequelize migration:create --name name_of_your_migration

Файл миграции будет выглядеть так:

module.exports = {
  up: function(queryInterface, Sequelize) {
    // logic for transforming into the new state
    return queryInterface.addColumn(
      'Todo',
      'completed',
     Sequelize.BOOLEAN
    );

  },

  down: function(queryInterface, Sequelize) {
    // logic for reverting the changes
    return queryInterface.removeColumn(
      'Todo',
      'completed'
    );
  }
}

А затем запустите его:

$ sequelize db:migrate

Ответ 2

Если вы хотите добавить несколько столбцов в одну таблицу, оберните все в Promise.all() и поместите столбцы, которые вы хотите добавить, в массив:

module.exports = {
  up: (queryInterface, Sequelize) => {
    return Promise.all([
      queryInterface.addColumn(
        'tableName',
        'columnName1',
        {
          type: Sequelize.STRING
        }
      ),
      queryInterface.addColumn(
        'tableName',
        'columnName2',
        {
          type: Sequelize.STRING
        }
      ),
    ]);
  },

  down: (queryInterface, Sequelize) => {
    return Promise.all([
      queryInterface.removeColumn('tableName', 'columnName1'),
      queryInterface.removeColumn('tableName', 'columnName2')
    ]);
  }
};

Вы можете иметь любой тип столбца, поддерживаемый sequelize https://sequelize.readthedocs.io/en/2.0/api/datatypes/

Ответ 3

Если вы работаете в vscode, вы можете добавить определение типа в файл миграции. который помогает идентифицировать все методы QueryInterface и sequelize.

 module.exports = {
/**
   * @typedef {import('sequelize').Sequelize} Sequelize
   * @typedef {import('sequelize').QueryInterface} QueryInterface
   */

  /**
   * @param {QueryInterface} queryInterface
   * @param {Sequelize} Sequelize
   * @returns
   */
  up: function(queryInterface, Sequelize) {
    // logic for transforming into the new state
    return queryInterface.addColumn(
      'Todo',
      'completed',
     Sequelize.BOOLEAN
    );

  },

  down: function(queryInterface, Sequelize) {
    // logic for reverting the changes
    return queryInterface.removeColumn(
      'Todo',
      'completed'
    );
  }
}

Который обеспечит intellisense, как показано ниже sequelize intellisense

Ответ 4

В соответствии с предложением Pter обернуть Promise в транзакцию, здесь пример использования async/await и транзакции (из документов с исправлением ошибки при создании индекса):

'use strict';

module.exports = {
    async up(queryInterface, Sequelize) {
        const transaction = await queryInterface.sequelize.transaction();
        try {
            await queryInterface.addColumn(
                'Todo',
                'completed',
                {
                    type: Sequelize.STRING,
                },
                { transaction }
            );

            await queryInterface.addIndex(
                'Todo',
                {
                    fields: ['completed'],
                    unique: true,
                },
                { transaction }
            );

            await transaction.commit();
        } catch (err) {
            await transaction.rollback();
            throw err;
        }
    },

    async down(queryInterface, Sequelize) {
        const transaction = await queryInterface.sequelize.transaction();
        try {
            await queryInterface.removeColumn(
                'Todo',
                'completed',
                { transaction }
            );

            await transaction.commit();
        } catch (err) {
            await transaction.rollback();
            throw err;
        }
    }
};