Skip to content

Instantly share code, notes, and snippets.

@JeremyBernier
Created February 5, 2020 23:39
Show Gist options
  • Save JeremyBernier/5683ebc8e83990a4d4e3d0abd1a9549d to your computer and use it in GitHub Desktop.
Save JeremyBernier/5683ebc8e83990a4d4e3d0abd1a9549d to your computer and use it in GitHub Desktop.
TypeORM upsert
import { getRepository, InsertResult } from "typeorm";
/**
* Upsert for TypeORM on PostgreSQL
* Returns InsertResult object (contains ID)
* @param repo Repository
* @param {object | object[]} data Data to upsert. Can be object or array
* @param {string} primaryKey Name of column that is primary key
* @returns {Promise<InsertResult>}
*/
export default function upsert(Entity, data, primaryKey: string): Promise<InsertResult> {
const repo = getRepository(Entity);
const row = Array.isArray(data) ? data[0] : data;
const keys = Object.keys(row);
if (keys.length < 1) {
throw new Error("Cannot upsert without any values specified");
}
const updateStr = keys.map(key => `"${key}" = EXCLUDED."${key}"`).join(",");
return repo
.createQueryBuilder()
.insert()
.values(data)
.onConflict(`("${primaryKey}") DO UPDATE SET ${updateStr}`)
.execute();
}
@JeremyBernier
Copy link
Author

JeremyBernier commented Feb 5, 2020

TypeORM doesn't have an upsert() function and I couldn't find any others that worked, so here's mine for PostgreSQL.

Technically the updateStr doesn't need to include the primary key unless the primary key is the only key (assuming we want to return the record). But for the sake of code simplicity, we're including it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment