objection.js: Bug: whereNotExists missing from generated query
I have this query:
app.db.Text.query().whereNotExists({
"textId": request.body.textId,
"languageCode": text.languageCode,
}).insert({
"textId": request.body.textId,
"languageCode": text.languageCode,
"content": text.content,
"contentOrigin": text.contentOrigin,
})
It produces this output:
insert into "maptionnaire"."MultilingualText" ("content", "contentOrigin", "languageCode", "textId") values ('LOL', 'userEntry', '??', 'test') returning "textId", "languageCode"
{ method: 'insert',
options: {},
timeout: false,
cancelOnTimeout: false,
bindings: [ 'LOL', 'userEntry', '??', 'test' ],
__knexQueryUid: '49df64ca-0730-49c6-884f-c5e00e9d5a98',
sql: 'insert into "maptionnaire"."MultilingualText" ("content", "contentOrigin", "languageCode", "textId") values (?, ?, ?, ?) returning "textId", "languageCode"',
returning: [ 'textId', 'languageCode' ] }
And because the where not exists
clause is missing from the generated query I then get this error:
{ error: insert into "maptionnaire"."MultilingualText" ("content", "contentOrigin", "languageCode", "textId") values ($1, $2, $3, $4) returning "textId", "languageCode" - duplicate key value violates unique constraint "MultilingualText_pkey"
at Connection.parseE (/Users/pineapple/git/mapita/maptionnaire2/src/server/node_modules/pg/lib/connection.js:567:11)
at Connection.parseMessage (/Users/pineapple/git/mapita/maptionnaire2/src/server/node_modules/pg/lib/connection.js:391:17)
at Socket.<anonymous> (/Users/pineapple/git/mapita/maptionnaire2/src/server/node_modules/pg/lib/connection.js:129:22)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at readableAddChunk (_stream_readable.js:176:18)
at TCP.onread (net.js:547:20)
name: 'error',
length: 241,
severity: 'ERROR',
code: '23505',
detail: 'Key ("textId", "languageCode")=(test, ??) already exists.',
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: 'maptionnaire',
table: 'MultilingualText',
column: undefined,
dataType: undefined,
constraint: 'MultilingualText_pkey',
file: 'nbtinsert.c',
line: '406',
routine: '_bt_check_unique' }
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 20 (7 by maintainers)
For any future users trying to write an upsert with objection/knex, here is my solution:
The
insertion
argument is an object like would be passed tomodel.query().insert(...)
.conflictIds
is an array of columns to look at for conflicts, by default the model’s primary keys.This should work for psql versions 9.5 and above. It will not work for prior versions of postgres or for other sql databases.