node.js 如何在 Sequelize CLI 中添加、删除新列

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46357533/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 18:29:14  来源:igfitidea点击:

How to Add, Delete new Columns in Sequelize CLI

node.jssequelize.jspsqlsequelize-cli

提问by Gijo Varghese

I've just started using Sequelize and Sequelize CLI

我刚刚开始使用 Sequelize 和 Sequelize CLI

Since it's a development time, there are a frequent addition and deletion of columns. What the best the method to add a new column to an existing model?

由于是开发时期,列的增删比较频繁。向现有模型添加新列的最佳方法是什么?

For example, I want to a new column 'completed' to Todomodel. I'll add this column to models/todo.js. Whats the next step?

例如,我想将新列“已完成”添加到Todo模型。我会将此列添加到models/todo.js。下一步是什么?

I tried sequelize db:migrate

我试过 sequelize db:migrate

not working: "No?migrations?were?executed,?database?schema?was?already?up?to?date."

不工作:“没有?迁移?被执行?数据库?模式?是?已经?更新?到?最新。”

回答by Maria Ines Parnisari

If you are using sequelize-cliyou need to create the migration first. This is just a file that tells the engine how to update the database and how to roll back the changes in case something goes wrong. You should always commit this file to your repository

如果您使用sequelize-cli,则需要先创建迁移。这只是一个文件,告诉引擎如何更新数据库以及如何在出现问题时回滚更改。您应该始终将此文件提交到您的存储库

$ sequelize migration:create --name name_of_your_migration

The migration file would look like this:

迁移文件如下所示:

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'
    );
  }
}

And then, run it:

然后,运行它:

$ sequelize db:migrate

回答by thedanotto

If you want to add multiple columns to the same table, wrap everything in a Promise.all()and put the columns you'd like to add within an array:

如果要将多个列添加到同一个表中,Promise.all()请将所有内容包装在 a 中并将要添加的列放入数组中:

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')
    ]);
  }
};

You can have any column type supported by sequelize https://sequelize.readthedocs.io/en/2.0/api/datatypes/

您可以拥有 sequelize https://sequelize.readthedocs.io/en/2.0/api/datatypes/支持的任何列类型

回答by NS23

If you are working in vscode, you can add type definition in the migration file. which helps to identify all the methods QueryInterface and sequelize provide.

如果你在 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'
    );
  }
}

Which will provide intellisense like below sequelize intellisense

这将提供如下智能感知 续集智能感知

回答by GavinBelson

To add multiple columns in sequelize

在 sequelize 中添加多列

Step 1:generate empty migration

第 1 步:生成空迁移

sequelize migration:generate --name custom_name_describing_your_migration

sequelize migration:generate --name custom_name_describing_your_migration

Step 2:add columns to the empty migration

第 2 步:将列添加到空迁移

Use a transaction as per the docs https://sequelize.org/master/manual/migrations.html#migration-skeleton:

根据文档https://sequelize.org/master/manual/migrations.html#migration-skeleton使用事务:

module.exports = {
    up: (queryInterface, Sequelize) => {
        return queryInterface.sequelize.transaction((t) => {
            return Promise.all([
                queryInterface.addColumn('table_name', 'field_one_name', {
                    type: Sequelize.STRING
                }, { transaction: t }),
                queryInterface.addColumn('table_name', 'field_two_name', {
                    type: Sequelize.STRING,
                }, { transaction: t })
            ])
        })
    },

    down: (queryInterface, Sequelize) => {
        return queryInterface.sequelize.transaction((t) => {
            return Promise.all([
                queryInterface.removeColumn('table_name', 'field_one_name', { transaction: t }),
                queryInterface.removeColumn('table_name', 'field_two_name', { transaction: t })
            ])
        })
    }
};

Step 3:run the migration

第 3 步:运行迁移

sequelize db:migrate

sequelize db:migrate

回答by Tim Newton

Per Pter suggestion to wrap Promise in a transaction, here's a sample using async/await and a transaction (from docs with bug fix when creating an index):

根据将 Promise 包装在事务中的 Pter 建议,这里有一个使用 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;
        }
    }
};

回答by Srujal Patel

I think if you check your column inside a particular table before adding or removing it, that would be great. This will remove error if the column already exists.

我认为如果您在添加或删除特定表之前检查您的列,那会很棒。如果该列已存在,这将删除错误。

'use strict';

module.exports = {
  // result_description
  up: async (queryInterface, Sequelize) => {
    let tableName = 'yourTableName';
    let columnName1 = 'columnName1';
    let columnName2 = 'columnName1';
    return Promise.all([
      queryInterface.describeTable(tableName)
        .then(tableDefinition => {
          if (tableDefinition.columnName1) return Promise.resolve();

          return queryInterface.addColumn(
            tableName,
            columnName1,
            {
              type: Sequelize.INTEGER,
              allowNull: false
            }
          );
        }),
      queryInterface.describeTable(tableName)
        .then(tableDefinition => {
          if (tableDefinition.columnName2) return Promise.resolve();

          return queryInterface.addColumn(
            tableName,
            columnName2,
            {
              type: Sequelize.STRING,
              allowNull: false
            }
          );
        })
    ]);
  },

  down: (queryInterface, Sequelize) => {

    let tableName = 'TestList';
    let columnName1 = 'totalScore';
    let columnName2 = 'resultDescription';
    return Promise.all([
      queryInterface.describeTable(tableName)
        .then(tableDefinition => {
          if (tableDefinition.columnName1) return Promise.resolve();
          return queryInterface.removeColumn(tableName, columnName1)
        }),
      queryInterface.describeTable(tableName)
        .then(tableDefinition => {
          if (tableDefinition.columnName1) return Promise.resolve();
          return queryInterface.removeColumn(tableName, columnName2)
        }),
    ]);
  }
};