Skip to content

Instantly share code, notes, and snippets.

@antoine-pous
Last active November 11, 2023 21:17
Show Gist options
  • Save antoine-pous/9a7ebbe3f6339ceb63d3f6fb6e90308a to your computer and use it in GitHub Desktop.
Save antoine-pous/9a7ebbe3f6339ceb63d3f6fb6e90308a to your computer and use it in GitHub Desktop.
TypeORM upsert
const upsert = async <Entity>(entity: ObjectType<Entity>, data: Entity, m: EntityManager, rawPKName: string = 'id'): Promise<InsertResult> => {
const keys: string[] = Object.keys(data)
if(keys.length < 1) {
throw Error(`Cannot upsert empty ${entity?.name || entity.constructor.name}`)
}
const updateStr: string = keys.map(key => `"${key}" = EXCLUDED."${key}"`).join(',')
return m.getRepository(entity)
.createQueryBuilder()
.insert()
.values(data)
.onConflict(`("${rawPKName}") DO UPDATE SET ${updateStr}`)
.execute()
}
@antoine-pous
Copy link
Author

Strong typed upsert function for TypeORM

This function works as intended for my own usage, I'm sharing it without restriction. Feel free to enhance it to make it even more generic but still typed.

Arguments

  • Entity: This is your raw entity class, this function does not support shema
  • data: This is you new data, using a new instance of your Entity
  • EntityManager: pass an entity manager instance, useful when you're using transactions
  • Raw PK Name: by default it will use id, but you can specify any PK name like it is in your DB

Usage

const data: MyEntity = new MyEntity()
data.key = 'value'

upsert(MyEntity, data, getConnection().manager)
  .then(console.log)
  .catch(console.error)

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