【问题标题】:Duplicate migrations when using "enumName" ColumnOption for a Postgres enum type对 Postgres 枚举类型使用“enumName”ColumnOption 时重复迁移
【发布时间】:2021-08-03 02:59:59
【问题描述】:

我有一个名为TaskNotification 的实体,其中我有一个名为type 的枚举字段。我使用enumName 选项在数据库中为其指定特定名称TaskNotificationType

import { Entity, Column } from 'typeorm';

export enum TaskNotificationType {
  ASSIGNED
}

@Entity('taskNotifications')
export class TaskNotification {
  @Column({
    type: 'enum',
    enum: TaskNotificationType,
    enumName: 'TaskNotificationType',
    default: TaskNotificationType.ASSIGNED,
  })
  type: TaskNotificationType;

  /* Some more code */
}

当我为此实体类创建新迁移时,我得到以下迁移。这是正确的,也是预期的。

import {MigrationInterface, QueryRunner} from "typeorm";

export class addNotifications1620795716886 implements MigrationInterface {
    name = 'addNotifications1620795716886'

    public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`CREATE TYPE "TaskNotificationType" AS ENUM('0')`);
        await queryRunner.query(`CREATE TABLE "taskNotifications" ("id" character varying(21) NOT NULL, "senderID" character varying(21) NOT NULL, "taskID" character varying(21) NOT NULL, "type" "TaskNotificationType" NOT NULL DEFAULT '0', CONSTRAINT "PK_bf03149248aee7c64532028321e" PRIMARY KEY ("id"))`);
        await queryRunner.query(`CREATE TABLE "notificationStatuses" ("id" character varying(21) NOT NULL, "receiverID" character varying(21) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "sentAt" TIMESTAMP WITH TIME ZONE, "readAt" TIMESTAMP WITH TIME ZONE, "taskNotificationID" character varying(21) NOT NULL, CONSTRAINT "PK_735fedb2f492dc91b0adf8233b0" PRIMARY KEY ("id"))`);
        await queryRunner.query(`ALTER TABLE "taskNotifications" ADD CONSTRAINT "FK_9b92958e250c1f46393e0e88066" FOREIGN KEY ("taskID") REFERENCES "tasks"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
        await queryRunner.query(`ALTER TABLE "notificationStatuses" ADD CONSTRAINT "FK_14dbeaea4a320e7375cb22e7e7a" FOREIGN KEY ("taskNotificationID") REFERENCES "taskNotifications"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
    }

    public async down(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`ALTER TABLE "notificationStatuses" DROP CONSTRAINT "FK_14dbeaea4a320e7375cb22e7e7a"`);
        await queryRunner.query(`ALTER TABLE "taskNotifications" DROP CONSTRAINT "FK_9b92958e250c1f46393e0e88066"`);
        await queryRunner.query(`DROP TABLE "notificationStatuses"`);
        await queryRunner.query(`DROP TABLE "taskNotifications"`);
        await queryRunner.query(`DROP TYPE "TaskNotificationType"`);
    }

}

当我重建应用程序并运行迁移时,数据库会根据我的需要进行更新。所以到目前为止没有任何问题。 ????

但是,如果我尝试在不更改任何实体的情况下创建另一个迁移,我将得到另一个迁移,如下所示。请注意updown 方法之间枚举中的名称差异。 (这里发生了什么???????)

import {MigrationInterface, QueryRunner} from "typeorm";

export class addNotificationsDuplicate1620795984398 implements MigrationInterface {
    name = 'addNotificationsDuplicate1620795984398'

    public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`ALTER TABLE "taskNotifications" DROP COLUMN "type"`);
        await queryRunner.query(`ALTER TABLE "taskNotifications" ADD "type" "TaskNotificationType" NOT NULL DEFAULT '0'`);
    }

    public async down(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`ALTER TABLE "taskNotifications" DROP COLUMN "type"`);
        await queryRunner.query(`ALTER TABLE "taskNotifications" ADD "type" "tasknotificationtype" NOT NULL DEFAULT '0'`);
    }

}

如果我没有在列选项中使用enumName,typeorm 将分配一个默认名称taskNotifications_type_enum

这里是迁移:

      
import {MigrationInterface, QueryRunner} from "typeorm";
    
export class addNotifications1620796454176 implements MigrationInterface {
    name = 'addNotifications1620796454176'
    
    public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`CREATE TYPE "taskNotifications_type_enum" AS ENUM('0')`);
        await queryRunner.query(`CREATE TABLE "taskNotifications" ("id" character varying(21) NOT NULL, "senderID" character varying(21) NOT NULL, "taskID" character varying(21) NOT NULL, "type" "taskNotifications_type_enum" NOT NULL DEFAULT '0', CONSTRAINT "PK_bf03149248aee7c64532028321e" PRIMARY KEY ("id"))`);
        await queryRunner.query(`CREATE TABLE "notificationStatuses" ("id" character varying(21) NOT NULL, "receiverID" character varying(21) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "sentAt" TIMESTAMP WITH TIME ZONE, "readAt" TIMESTAMP WITH TIME ZONE, "taskNotificationID" character varying(21) NOT NULL, CONSTRAINT "PK_735fedb2f492dc91b0adf8233b0" PRIMARY KEY ("id"))`);
        await queryRunner.query(`ALTER TABLE "taskNotifications" ADD CONSTRAINT "FK_9b92958e250c1f46393e0e88066" FOREIGN KEY ("taskID") REFERENCES "tasks"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
        await queryRunner.query(`ALTER TABLE "notificationStatuses" ADD CONSTRAINT "FK_14dbeaea4a320e7375cb22e7e7a" FOREIGN KEY ("taskNotificationID") REFERENCES "taskNotifications"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
        }
    
    public async down(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`ALTER TABLE "notificationStatuses" DROP CONSTRAINT "FK_14dbeaea4a320e7375cb22e7e7a"`);
        await queryRunner.query(`ALTER TABLE "taskNotifications" DROP CONSTRAINT "FK_9b92958e250c1f46393e0e88066"`);
        await queryRunner.query(`DROP TABLE "notificationStatuses"`);
        await queryRunner.query(`DROP TABLE "taskNotifications"`);
        await queryRunner.query(`DROP TYPE "taskNotifications_type_enum"`);
        }
    
}

然后,如果我尝试在不更改实体的情况下生成迁移,则不会生成新的迁移。 (这是正确的预期行为)

但是,如果我在那之后添加enumName,它不会为名称更改生成新的迁移。当我们尝试在不更改任何实体的情况下运行迁移时,它会抛出我们看到的常见错误。 (又破了???)

╰>>> npm run typeorm:novadelite migration:generate -- -n addNotificationsDuplicate

> novade-lite-backend@0.1.4 typeorm:novadelite /Users/eranga/Documents/Projects/Novade/NovadeLiteBackend
> ts-node ./node_modules/.bin/typeorm --config src/modules/Database/OrmConfigs/novadeLiteOrmConfig "migration:generate" "-n" "addNotificationsDuplicate"

No changes in database schema were found - cannot generate a migration. To create a new empty migration use "typeorm migration:create" command

这里出了什么问题,如何使用 typeorm 为我的枚举类型指定特定名称?

非常感谢任何帮助! ????


(在极少数情况下这是 typeorm 中的问题,我已经创建了一个 issue in Github

【问题讨论】:

    标签: postgresql enums nestjs typeorm


    【解决方案1】:

    这确实是 Typeorm 中的一个问题,并由 AlexMesserthis PR 中修复。 ?

    在撰写本文时,Typeorm 的版本是0.2.32,此修复将在下一个版本中发布! ???

    【讨论】:

      猜你喜欢
      • 2021-01-08
      • 2020-03-13
      • 2021-04-28
      • 1970-01-01
      • 2021-01-23
      • 2023-03-28
      • 2019-12-08
      • 2020-05-27
      • 1970-01-01
      相关资源
      最近更新 更多