Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't set updatedAt from onConflict #617

Closed
romeerez opened this issue Jul 27, 2023 · 3 comments · Fixed by #792
Closed

Can't set updatedAt from onConflict #617

romeerez opened this issue Jul 27, 2023 · 3 comments · Fixed by #792
Labels
bug Something isn't working postgres Related to PostgreSQL typescript Related to Typescript

Comments

@romeerez
Copy link

Hi, and thanks for maintaining this wonderful library!

I encountered a problem trying to set updatedAt inside onConflict.

interface ItemTable {
  uniqueKey: string;
  value: number;
  // maybe I can change something here?
  updatedAt: ColumnType<Date, never, string | undefined>;
}

type NewItem = Insertable<ItemTable>;

interface Database {
  item: ItemTable;
}

const dialect = new PostgresDialect({
  pool: new Pool({ ...config }),
});

const db = new Kysely<Database>({
  dialect,
});

function upsertItems(
  items: NewItem[]
): Promise<InsertResult[]> {
  return db
    .insertInto("item")
    .values(items)
    .onConflict((oc) =>
      oc.column("uniqueKey").doUpdateSet({
        // no problem setting a regular value:
        value: (eb) => eb.ref("excluded.value"),
        // TS error on the following line
        updatedAt: (eb) => eb.ref("excluded.updatedAt"),
      })
    )
    .execute();
}

TS error:

Property '#private' in type 'ExpressionWrapper' refers to a different member that cannot be accessed from within type 'SelectQueryBuilder'

Looks like the problem is related to the fact that updatedAt is defined using ColumnType.

It's not critical though, I worked this around by changing the line inside onConflict to:

updatedAt: (eb) => eb.sql`now()`,
@koskimas
Copy link
Member

koskimas commented Jul 27, 2023

We might be using the insert type there, even though we should be using the update type. Thanks for the issue! We'll take a look soon.

@igalklebanov igalklebanov added bug Something isn't working typescript Related to Typescript labels Jul 27, 2023
@igalklebanov igalklebanov added the postgres Related to PostgreSQL label Dec 3, 2023
@ejabu
Copy link

ejabu commented Jun 8, 2024

updatedAt: (eb) => eb.sqlnow(),

This above syntax seems outdated.

As workaround I used this.

import { sql } from 'kysely';


export const bulkInsert = (rows: NewIssues[]) => {
  const query = kyselyDB
    .insertInto('table_name')
    .values(rows)
    .onConflict((oc) =>
      oc.column('id').doUpdateSet({
        updatedAt: (eb) => sql`now()`,
        id: (eb) => eb.ref('excluded.id'),
      }),
    )
    .compile();

  console.log('sql =>\n', query.sql);
  console.log('sql =>\n', query.parameters);
  return query;
};

@mb21
Copy link

mb21 commented Sep 12, 2024

For those looking for a generic way to update all fields, see #677 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working postgres Related to PostgreSQL typescript Related to Typescript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants