django-postgres-extra icon indicating copy to clipboard operation
django-postgres-extra copied to clipboard

Mark updated rows on conflict

Open IlyaSemenov opened this issue 4 years ago • 3 comments

Currently with on_conflict(...).insert(...) (as well as insert_and_get and bulk_insert) there is no way to know which rows were inserted and which have been updated in-place (unlike Django's update_or_create which returns a tuple of obj, created).

However, Postgres provides such trick with RETURNING *, (xmax = 0) (see https://stackoverflow.com/a/47001830/189806).

It would be great if that was supported natively by the library.

IlyaSemenov avatar May 11 '20 18:05 IlyaSemenov

FWIW, I ended up using this (definitely ugly) monkey patch:

import psqlextra.compiler


class PostgresInsertCompiler(psqlextra.compiler.PostgresInsertCompiler):
    def _rewrite_insert_update(self, sql, params, returning):
        return super()._rewrite_insert_update(
            sql, params, returning + ",(xmax = 0) AS _is_new"
        )


psqlextra.compiler.PostgresInsertCompiler = PostgresInsertCompiler

IlyaSemenov avatar May 15 '20 10:05 IlyaSemenov

@Photonios any plan for implementing this functionality?

talperetz avatar Sep 07 '21 21:09 talperetz

@IlyaSemenov @talperetz if you need a work-around, https://github.com/Opus10/django-pgbulk supports this

wesleykendall avatar Aug 17 '22 21:08 wesleykendall