首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >sequelize.js迁移执行序列

sequelize.js迁移执行序列
EN

Stack Overflow用户
提问于 2019-03-21 19:16:57
回答 3查看 2.6K关注 0票数 1

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

代码语言:javascript
复制
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 }
    ),
  ])
),

当我执行它的时候,order以一种奇怪的方式混淆了:

代码语言:javascript
复制
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;

正因为如此,我得到了错误:

代码语言:javascript
复制
ERROR: column "status" of relation "users" already exists

有没有办法让这些查询以特定的顺序运行?

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

代码语言:javascript
复制
      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";
EN

回答 3

Stack Overflow用户

发布于 2019-03-21 21:18:03

之所以会发生这种情况,是因为您使用的是并行执行promises的Promise.all。不能保证您的承诺将按照它们定义的顺序执行。因此您需要使用.then方法来相应地执行您工作流。

代码语言:javascript
复制
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(...);
),
票数 1
EN

Stack Overflow用户

发布于 2019-03-22 00:35:12

正如尤金所指出的,你的问题在于你使用Promise.all调用你所有的迁移。我强烈建议做单独的迁移文件。这样,你就有了一个更好的项目结构,并且更容易被新的开发人员理解。

用于创建迁移的命令:

代码语言:javascript
复制
sequelize migration:generate --name [name-of-your-migration]

要执行创建订单上的所有迁移以及尚未运行的迁移,请执行以下操作:

代码语言:javascript
复制
sequelize db:migrate
票数 0
EN

Stack Overflow用户

发布于 2020-04-17 19:14:36

可以使用带有{concurrency: 1}选项的bluebirdjs Promise.map函数,如下所示:

代码语言:javascript
复制
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 promises

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55279224

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档