Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@amorgun
Created November 10, 2017 10:51
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save amorgun/2a04764f0fc80e646efeb79cd7ad0b70 to your computer and use it in GitHub Desktop.
Save amorgun/2a04764f0fc80e646efeb79cd7ad0b70 to your computer and use it in GitHub Desktop.
SqlAlchemy postgres bulk upsert
from sqlalchemy.dialects import postgresql
def bulk_upsert(session: Session,
items: Sequence[Mapping[str, Any]]):
session.execute(
postgresql.insert(MyModel.__table__)
.values(items)
.on_conflict_do_update(
index_elements=[MyModel.id],
set_={MyModel.my_field.name: 'new_value'},
)
)
@franz101
Copy link

franz101 commented Jul 1, 2020

Made my day!

@xoelop
Copy link

xoelop commented Dec 10, 2020

Is there a way to pass to set_ in on_conflict_do_update a list of values from items, instead of a default value for all the records being upserted?

@mzealey
Copy link

mzealey commented Jun 5, 2021

Following works a bit better:

  session.execute(
    postgresql.insert(MyModel.__table__)
    .values(items)
    .on_conflict_do_update(
      index_elements=MyModel.__table__.primary_key.columns,
      set_=items
    )
  )

@NikZak
Copy link

NikZak commented May 6, 2022

Actually the correction does not seem to be working
ValueError: set parameter must be a non-empty dictionary or a ColumnCollection such as the .c. collection of a Table object
the items have to be dict, can't have a Sequence[Mapping] as in here

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