Skip to content

Instantly share code, notes, and snippets.

@csotiriou
Forked from plurch/upsert.js
Last active August 27, 2016 18:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save csotiriou/f82cf28d0e72bf13dd9808f1647d7f37 to your computer and use it in GitHub Desktop.
Save csotiriou/f82cf28d0e72bf13dd9808f1647d7f37 to your computer and use it in GitHub Desktop.
PostgreSQL 9.5 Upsert using Knex.js
exports.knex = require('knex')({
client: 'pg',
connection: {
host : '127.0.0.1',
user : 'your_database_user',
password : 'your_database_password',
database : 'myapp_test'
}
});
/**
* Perform an "Upsert" using the "INSERT ... ON CONFLICT ... " syntax in PostgreSQL 9.5
* @link http://www.postgresql.org/docs/9.5/static/sql-insert.html
* @author https://github.com/plurch
*
* @param {string} tableName - The name of the database table
* @param {string} conflictTarget - The column in the table which has a unique index constraint
* @param {Object} itemData - a hash of properties to be inserted/updated into the row
* @returns {Promise} - A Promise which resolves to the inserted/updated row
*/
function upsertItems(tableName : string, conflictTarget : string, itemData : any) {
let firstObjectIfArray = Array.isArray(itemData) ? itemData[0] : itemData;
let exclusions = Object.keys(firstObjectIfArray)
.filter(c => c !== conflictTarget)
.map(c => knex.raw('?? = EXCLUDED.??', [c, c]).toString())
.join(",\n");
let insertString = knex(tableName).insert(itemData).toString();
let conflictString = knex.raw(` ON CONFLICT (??) DO UPDATE SET ${exclusions} RETURNING *;`, conflictTarget).toString();
let query = (insertString + conflictString).replace(/\?/g, '\\?');
return knex.raw(query)
.on('query', data => console.log('Knex: ' + data.sql))
.then(result => result.rows);
};
let tableName = 'user_meta';
let conflictTarget = 'login';
let itemData = {
login: 'plurch',
user_id: 3332519
};
let resultPromise = upsertItem(tableName, conflictTarget, itemData);
resultPromise.then(userMeta => console.log('Processed this user: ' + userMeta.login));
//
// This query will be generated:
//
// insert into "user_meta" ("login", "user_id") values ('plurch', '3332519') ON CONFLICT ("login") DO UPDATE SET "user_id" = EXCLUDED."user_id" RETURNING *;
//
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment