sequelize / sequelize-typescript

Decorators and some other features for sequelize
MIT License
2.78k stars 280 forks source link

[BUG] ForeignKey and non-ForeignKeys as unique generates extra constraint #894

Open cskiwi opened 3 years ago

cskiwi commented 3 years ago

Versions

UPDATE: Just updated to latest version (v6) issue still persists

I'm submitting a ...

Actual behavior:

My many to many releationship is unique for a combination of 3 values (the 2 external id's and a date). However any configuration creates a unique constraint on the 2 ForeignKeys. So this doesn't allow inserts even if that 3th value is different

Error:

ERROR:  duplicate key value violates unique constraint "ClubMemberships_playerId_clubId_key"
DETAIL:  Key ("playerId", "clubId")=(1, 1) already exists.
SQL state: 23505

Expected behavior:

if you have @PrimaryKey on ForeignKeys and non-Foreignkeys, no creation of a constraint on those foreign keys. or a way to disable it.

I tried numerous combinations of @PrimaryKey, @Unique but non seem to give any correct result

Steps to reproduce:

Use the code below and .sync({force: true})

Related code:

@Table
export class ClubMembership extends Model<ClubMembership> {
  constructor(values?: Partial<ClubMembership>, options?: BuildOptions) {
    super(values, options);
  }

  @ForeignKey(() => Player)
  @Unique('unique_constraint')
  @Column
  playerId: string;

  @ForeignKey(() => Club)
  @Unique('unique_constraint')
  @Column
  clubId: string;

  @Unique('unique_constraint')
  @Column
  start: Date;

}

this generates: image

If I would have the option to disable the automatic creation of the unique constraint I would be happy :)

note: I know I can remove that constraint via migrations, but this doesnt work for my tests

cskiwi commented 3 years ago

For other people coming across this issue, I've found a hacky way to resolve this:

By placing the following exact key on the start column : @Unique('ClubMemberships_clubId_playerId_unique'). it combined the 2 unique instances and gave the wanted result.

If you are having issues finding the unique string:

this will spit out each unique key when doing a sync