последовательность выполнения миграции sequelize.js - PullRequest
0 голосов
/ 21 марта 2019

У меня есть несколько запросов, которые я хочу выполнить в одной и той же миграции. Они связаны, поэтому они должны быть выполнены в определенном порядке. Это метод перехода моей миграции:

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";

Ответы [ 2 ]

0 голосов
/ 21 марта 2019

Как отметил Евгений, ваша проблема в том, что вы вызываете все свои миграции с Promise.all. Я настоятельно рекомендую делать отдельные файлы миграции. Таким образом, вы получите лучшую структуру вашего проекта и будете более понятны для новых разработчиков.

команда для создания миграции:

sequelize migration:generate --name [name-of-your-migration]

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

sequelize db:migrate
0 голосов
/ 21 марта 2019

Это происходит потому, что вы используете Promise.all, который выполняет обещания параллельно. Нет никаких гарантий, что ваши обещания будут выполнены в том порядке, в котором они определены. Поэтому вам нужно использовать метод .then для последовательного выполнения рабочего процесса.

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(...);
),
...