Search code examples
sqlpostgresqlprimary-keytypeormcomposite-primary-key

Constraint "PK" of relation "table" does not exist when generating migration with typeorm


I have an ormconfig.ts like this:

const config: ConnectionOptions = {
  type: "postgres",
  host: "localhost",
  username: "postgres",
  password: "postgres",
  database: "dbname",
  entities: ["dist/database/entities/**/*.js"],
  migrations: ["dist/migration/**/*.js"],
  cli: {
    entitiesDir: "src/database/entities",
    migrationsDir: "src/migration",
  },
  synchronize: true,
  name: "app",
};

and an entity like so:

@Entity("follows")
export class Follow extends BaseEntity {
  @PrimaryColumn()
  followerAddress: string;

  @PrimaryColumn()
  followeeAddress: string;

  @OneToOne(() => User, (user) => user.address)
  @JoinColumn({ name: "followerAddress" })
  followerUser: User;

  @OneToOne(() => User, (user) => user.address)
  @JoinColumn({ name: "followeeAddress" })
  followeeUser: User;
}

If I rename the PrimaryColumns and make it like:

@Entity("follows")
export class Follow extends BaseEntity {
  @PrimaryColumn()
  followerAddressNew: string;

  @PrimaryColumn()
  followeeAddressNew: string;

  @OneToOne(() => User, (user) => user)
  @JoinColumn({ name: "followerAddress" })
  followerUser: User;

  @OneToOne(() => User, (user) => user)
  @JoinColumn({ name: "followeeAddress" })
  followeeUser: User;
}

Then I get the following error:

QueryFailedError: constraint "PK_0d65998d7ca318692c5021c8121" of relation "follows" does not exist

Synchronize is set to true, so I'm not sure if I need to generate and run a migration, but I tried that and got:

QueryFailedError: constraint "PK_439cf7d31c1f020884802168a8c" of relation "follows" does not exist

It seems that the generated migration file adds the constraint once and then drops it twice?

public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`ALTER TABLE "public"."follows" ADD "followerAddressfdsa" character varying NOT NULL`);
        await queryRunner.query(`ALTER TABLE "public"."follows" DROP CONSTRAINT "PK_3f7767cc6077ad78f956bffc8a7"`);
        await queryRunner.query(`ALTER TABLE "public"."follows" ADD CONSTRAINT "PK_59ecb7646bafb5e2ae63d6f8deb" PRIMARY KEY ("followerAddress", "followeeAddress", "followerAddressfdsa")`);
        await queryRunner.query(`ALTER TABLE "public"."follows" ADD "followeeAddressfdsa" character varying NOT NULL`);
        await queryRunner.query(`ALTER TABLE "public"."follows" DROP CONSTRAINT "PK_59ecb7646bafb5e2ae63d6f8deb"`);
        await queryRunner.query(`ALTER TABLE "public"."follows" ADD CONSTRAINT "PK_439cf7d31c1f020884802168a8c" PRIMARY KEY ("followerAddress", "followeeAddress", "followerAddressfdsa", "followeeAddressfdsa")`);
        await queryRunner.query(`ALTER TABLE "public"."follows" DROP CONSTRAINT "PK_439cf7d31c1f020884802168a8c"`);
        await queryRunner.query(`ALTER TABLE "public"."follows" ADD CONSTRAINT "PK_073836419485cc2ca626f9ce5a8" PRIMARY KEY ("followerAddressfdsa", "followeeAddressfdsa")`);
        await queryRunner.query(`ALTER TABLE "public"."follows" DROP CONSTRAINT "FK_e37f798c5697e8b84094d64a68f"`);
        await queryRunner.query(`ALTER TABLE "public"."follows" DROP CONSTRAINT "FK_70456987d622cd40a732aec83bd"`);
        await queryRunner.query(`ALTER TABLE "public"."follows" ALTER COLUMN "followerAddress" DROP NOT NULL`);
        await queryRunner.query(`ALTER TABLE "public"."follows" DROP CONSTRAINT "PK_439cf7d31c1f020884802168a8c"`);
        await queryRunner.query(`ALTER TABLE "public"."follows" ADD CONSTRAINT "PK_b9a8a76998607a9752a4d756814" PRIMARY KEY ("followeeAddress", "followerAddressfdsa", "followeeAddressfdsa")`);
        await queryRunner.query(`ALTER TABLE "public"."follows" ALTER COLUMN "followeeAddress" DROP NOT NULL`);
        await queryRunner.query(`ALTER TABLE "public"."follows" DROP CONSTRAINT "PK_b9a8a76998607a9752a4d756814"`);
        await queryRunner.query(`ALTER TABLE "public"."follows" ADD CONSTRAINT "PK_073836419485cc2ca626f9ce5a8" PRIMARY KEY ("followerAddressfdsa", "followeeAddressfdsa")`);
        await queryRunner.query(`ALTER TABLE "public"."follows" ADD CONSTRAINT "FK_e37f798c5697e8b84094d64a68f" FOREIGN KEY ("followerAddress") REFERENCES "users"("address") ON DELETE NO ACTION ON UPDATE NO ACTION`);
        await queryRunner.query(`ALTER TABLE "public"."follows" ADD CONSTRAINT "FK_70456987d622cd40a732aec83bd" FOREIGN KEY ("followeeAddress") REFERENCES "users"("address") ON DELETE NO ACTION ON UPDATE NO ACTION`);
    }

This line seems to be called twice:

    await queryRunner.query(`ALTER TABLE "public"."follows" DROP CONSTRAINT "PK_439cf7d31c1f020884802168a8c"`);

Solution

  • I don't know exactly what is happening with typeorm. Could be a bug with updating or creating schema using entity.

    But I ran into this exact same problem and I found out that the tables were already created in the database. I deleted all the tables that were already created and ran the application so that typeorm (re)created the tables. That solved the problem for me.

    I hope this works for you as well.