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

Suggestion on PostgreSQL INSERT ON CONFLICT (Upsert) #1121

Closed
ozum opened this issue Jan 2, 2016 · 8 comments
Closed

Suggestion on PostgreSQL INSERT ON CONFLICT (Upsert) #1121

ozum opened this issue Jan 2, 2016 · 8 comments

Comments

@ozum
Copy link
Contributor

ozum commented Jan 2, 2016

Hi,

Currently I'm using knex.raw for INSERT ON CONFLICT queries:

knex.raw('INSERT INTO table (id) VALUES (?) ON CONFLICT (id) DO UPDATE SET id = EXCLUDED.id RETURNING id', [id])
    .then((result) => {});

I want to benefit knex.insert and other methods at least part of the query for this type queries. Is there a better way to build this query using any combination of knex.select / knex.raw?

@RubenCordeiro
Copy link

I think that knex.raw is still the best way to write Upsert statements with KnexJS. Check the issue #54.

@hayeah
Copy link

hayeah commented Feb 14, 2016

I put together a monkey patch to experiment with upsert. See:

#54 (comment)

It works like this:

knex("oauths").insert(oauth).onConflict(["provider", "uid"],{
  info: profile,
  updated_at: new Date(),
});

@plurch
Copy link

plurch commented Mar 2, 2016

I wrote a relatively simple function which works for my use cases. It uses knex.insert and toString()

https://gist.github.com/plurch/118721c2216f77640232

@ivoneijr
Copy link

ivoneijr commented Aug 2, 2016

Nice Suggestion!

@duncanfinney
Copy link

@plurch Very cool. Thank you.

@elhigu
Copy link
Member

elhigu commented Apr 12, 2017

closing as duplicate #54

@ron-liu
Copy link

ron-liu commented Aug 9, 2019

I tried the solution @plurch mentioned. All good except it didn't escape ? properly. Check the below case:

Given the table definition:

create table abc (
	name varchar(100) PRIMARY KEY
)

And the below code:

  const insertSql = knex('abc')
    .insert({ name: '? - \\? - \\? - \\\\? # /? - //? - ///? - ////?' })
    .toString()
  console.log(insertSql)

  await knex.raw(insertSql)

It ends up with the below in the db:
$1 - $2 - $3 - $4 # /$5 - //$6 - ///$7 - ////$8

My working environment is:

  • macbook
  • postgres running on docker container: postgres:12-alpine

@ron-liu
Copy link

ron-liu commented Aug 9, 2019

I end up using the old school way as below:

const main = async () => {
  await knex('abc')
    .insert({ name: 'a' })
    .catch(x => {
      if (!isUniqueViolationError(x)) throw x
    })

  console.log('done')
}

main()

const isUniqueViolationError = err => err.code === '23505'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants