sequelize.js迁移执行序列

sequelize.js迁移执行序列,sequelize.js,sequelize-cli,Sequelize.js,Sequelize Cli,我想在同一个迁移中执行几个查询。它们是相关的,因此必须按特定顺序执行。这是我的迁移方法: up: (queryInterface, Sequelize) => queryInterface.sequelize.transaction(transaction => Promise.all([ queryInterface.renameColumn(table, 'status', 'status_temp', { transaction }), queryInter

我想在同一个迁移中执行几个查询。它们是相关的,因此必须按特定顺序执行。这是我的迁移方法:

up: (queryInterface, Sequelize) =>
queryInterface.sequelize.transaction(transaction =>
  Promise.all([
    queryInterface.renameColumn(table, 'status', 'status_temp', { transaction }),
    queryInterface.sequelize.query(
      'ALTER TYPE enum_users_status RENAME TO enum_users_status_temp;',
      {
        transaction
      }
    ),
    queryInterface.addColumn(
      table,
      'isActive',
      {
        allowNull: false,
        defaultValue: false,
        type: Sequelize.BOOLEAN
      },
      { transaction }
    ),
    queryInterface.bulkUpdate(
      table,
      {
        isActive: true
      },
      {
        status: 'active'
      },
      { transaction }
    ),
    queryInterface.addColumn(
      table,
      'status',
      {
        allowNull: false,
        defaultValue: STATUS_FREE,
        type: Sequelize.ENUM(STATUS_FREE, STATUS_BUSY, STATUS_DELETED)
      },
      { transaction }
    ),
  ])
),
当我在执行它时,命令以一种奇怪的方式混合在一起:

Executing (591dc838-4659-4de4-b605-54b7c03c527f): START TRANSACTION;
...
Executing (591dc838-4659-4de4-b605-54b7c03c527f): ALTER TYPE     enum_users_status RENAME TO enum_users_status_temp;
Executing (591dc838-4659-4de4-b605-54b7c03c527f): ALTER TABLE "public"."users" ADD COLUMN "isActive" BOOLEAN NOT NULL DEFAULT false;
Executing (591dc838-4659-4de4-b605-54b7c03c527f): UPDATE "users" SET "isActive"=true WHERE "status" = 'active'
Executing (591dc838-4659-4de4-b605-54b7c03c527f): CREATE TYPE "public"."enum_users_status" AS ENUM('free', 'busy', 'deleted');ALTER TABLE "public"."users" ADD COLUMN "status" "public"."enum_users_status" NOT NULL DEFAULT 'free';
Executing (591dc838-4659-4de4-b605-54b7c03c527f): ALTER TABLE "users" RENAME COLUMN "status" TO "status_temp";
Executing (591dc838-4659-4de4-b605-54b7c03c527f): ROLLBACK;
我得到的错误是因为:

ERROR: column "status" of relation "users" already exists
有没有办法让这些查询按特定顺序运行

UPD: 我的预期结果是这样的

      START TRANSACTION;
      ALTER TABLE "users" RENAME COLUMN "status" TO "status_temp";
      ALTER TYPE enum_users_status RENAME TO enum_users_status_temp;
      ALTER TABLE "public"."users" ADD COLUMN "isNew" BOOLEAN NOT NULL DEFAULT true;
      UPDATE "users" SET "isNew"=false WHERE "status_temp" = 'active';
      CREATE TYPE "public"."enum_users_status" AS ENUM('free', 'busy', 'deleted');
      ALTER TABLE "public"."users" ADD COLUMN "status" "public"."enum_users_status" NOT NULL DEFAULT 'free';
      UPDATE "users" SET "status"='busy' WHERE "isFree" = false;
      UPDATE "users" SET "status"='deleted' WHERE "status_temp" = 'deleted';
      ALTER TABLE "public"."users" DROP COLUMN "isFree";
      ALTER TABLE "public"."users" DROP COLUMN "status_temp";

发生这种情况是因为您正在使用
Promise.all
并行执行承诺。不能保证你的承诺会按规定的顺序执行。所以您需要使用
。然后
方法来执行您的工作流

up: (queryInterface, Sequelize) =>
queryInterface.sequelize.transaction(transaction =>
  queryInterface.renameColumn(table, 'status', 'status_temp', { transaction })
    .then(() => queryInterface.sequelize.query(
      'ALTER TYPE enum_users_status RENAME TO enum_users_status_temp;',
      {
        transaction
      }
    ))
    .then(...);
),

正如Eugene所指出的,您的问题是,您正在使用
Promise.all
调用所有迁移。我强烈建议您进行单独的文件迁移。这样,您的项目结构更好,新开发人员更容易理解

用于创建迁移的命令:

sequelize migration:generate --name [name-of-your-migration]
要执行创建顺序上的所有迁移以及尚未运行的迁移,请执行以下操作:

sequelize db:migrate

可以使用bluebirdjs函数和
{concurrency:1}
选项,如下所示:

const Promise = require('bluebird');
...

up: function (queryInterface, Sequelize) {
    return Promise.map([
            queryInterface.sequelize.query('SET FOREIGN_KEY_CHECKS = 0'),
            queryInterface.addColumn(
                'table1',
                'column1',
                {
                    type: Sequelize.INTEGER,
                    after: 'id',
                    defaultValue: 0
                }),
            queryInterface.sequelize.query('SET FOREIGN_KEY_CHECKS = 1'),
            queryInterface.addColumn(
                'table2',
                'column2',
                {
                    type: Sequelize.BOOLEAN,
                    after: 'column3',
                    defaultValue: 0
                })
        ],
        (promise) => promise,
        {concurrency: 1}
    );
}

注意:您可以将
concurrency
选项设置为
n
,以便同时执行
n
承诺

谢谢。但我不确定这是否是个好主意。我想把所有逻辑上相关的查询放在一个文件中。这个例子已经过时了,但我需要:1。再创建一个字段2。删除一个现有字段3。更改状态字段PS:所有这些字段中的数据都应该从以前版本的字段中迁移过来,这就是为什么我把它们放在一起的原因+因为迁移都在同一个文件夹中,我认为让extrasIs成为可能不是一个好主意,只需按照我编写它们的顺序在一个事务中进行查询,而不使用这些字段然后()重复?我不明白那()有什么问题?使用async/await如果您不喜欢,那么()您将无法使用示例中的事务为什么?没有区别,这只是一个执行命令