DrizzleORM use a unique index in conflict updates

25 views Asked by At

Given the following table:

user_id year roles (array)
0 2024 [defender]
0 2023 [attacker]
1 2024 [defender]

You can observe that we should have a unique entry for each user and year. So this table is correct, but inserting | 0 | 2024 | attacker | should replace update the first row instead.

To my knowledge, this means i should create a unique index for these, which I've done in drizzle as follows:

export const pianiExtra = pgTable(
  'players',
  {
    userId: uuid('user_id')
      .notNull()
      .references(() => users.id, { onDelete: 'cascade' }),
    year: bigint('year', { mode: 'number' }).notNull(),
    roles: roles('roles').array().notNull(),
  },
  (t) => ({
    playersUniqueIndex: unique('players_unique_index').on(t.userId, t.year),
  }),
);

Which brings me to the insert query:

const input = {
    userId: 0,
    year: 2024,
    roles: [defender, attacker]
}

const result = await ctx.db
      .insert(players)
      .values(input)
      .onConflictDoUpdate({
        target: [players.userId, players.year],
        set: input,
      })
      .returning({ id: pianiExtra.id });

There are two things that don;t quite make sense to me here:

  1. I would expect to pass the newly created index instead of the properties array in onConflictDoUpdate -> target.
  2. if I run this, I get a there is no unique or exclusion constraint matching the ON CONFLICT specification, which I suspect is related to the target as well.
0

There are 0 answers