Opened 2 weeks ago

Closed 2 weeks ago

Last modified 2 weeks ago

#36567 closed Uncategorized (duplicate)

Allow updating fields using expressions in bulk_create with update_conflicts

Reported by: Take Weiland Owned by:
Component: Uncategorized Version: 5.2
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

My use-case is as follows:
I have a list of objects that I need to "upsert" into the database. However one of the fields must only be updated if it has no value yet.
In raw SQL (PostgreSQL) I would write this as follows:

INSERT INTO my_table (id, user_id, field_a, field_b)
VALUES (...), (...), (...)
ON CONFLICT (user_id) DO UPDATE SET field_a = EXCLUDED.field_a, field_b = COALESCE(my_table.field_b, EXCLUDED.field_b)
RETURNING id;

There is no way to express this query using Django's ORM as far as I can tell.

INSERT ... ON CONFLICT is covered by bulk_create with update_conflicts. However it only lets you specify a list of fields to update.

Some API bike-shedding: I could imagine it being supported like this:

MyModel.objects.bulk_create(
  objs,
  update_conflicts=True,
  update_fields={
    'field_b': Coalesce(F('field_b'), Inserted('field_b'))
  }
)

Note the use of the pseudo DB-Function Inserted. It allows refering to the values that would originally be inserted. There is different syntax for this depending on the DB Vendor:

This functionality is already implemented in the database operations in on_conflict_suffix_sql, however it is hardcoded to not allow custom expressions.

Change History (2)

comment:1 by Take Weiland, 2 weeks ago

Resolution: duplicate
Status: newclosed
Note: See TracTickets for help on using tickets.
Back to Top