On 09/29/2014 01:56 AM, Anssi Kääriäinen wrote: > I think we could use UPSERT for our .save() logic. Django's save() > method is defined as: > - Insert a row in to the database if there isn't already a matching > row for the saved model's primary key > - Otherwise update the row > > This is currently implemented as "try to update, if nothing was updated, > then insert". Naturally, that approach has some race conditions. > > There are a couple of problems with the suggested INSERT ... ON > DUPLICATE KEY UPDATE feature for this use case: > 1. We need to use WITHIN primary_key_idx_name, but we don't > necessarily know the primary key index name of the table. It would be > extremely useful to have support for WITHIN PRIMARY KEY syntax. > 2. We need to know if the row was updated or if it was created > (post_save signal needs this information). Looking at the spec, it seems > this is possible to do by issuing a query: > INSERT ... ON DUPLICATE KEY UPDATE RETURNING primary_key_col; > and then, if nothing is returned, we know it was an update. However, I > see this way as problematic. if PostgreSQL ever wants to allow returning > the updated values on conflict, then using RETURNING primary_key_col; > wouldn't work any more. It seems somewhat likely that somebody will want > to add support for RETURNING for the ON CONFLICT UPDATE case later on. > > Using the proposed feature for create_or_update() method isn't that easy > - the problem is that the user is free to specify any filtering for the > model to be upserted. We would need to check if the filtering matches > some unique index exactly, and if it does, then do an INSERT ON > DUPLICATE KEY UPDATE WITHING uq_index_name, but we don't know the index > name.
Of course, it would be better for Django to reliably know index names. Even though we don't currently, I'm hopeful that https://github.com/django/deps/pull/6 may get us there by the time we would be considering these changes anyway, which would address both your #1 above, and the issues with create_or_update(). Carl -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/542992BD.2050501%40oddbird.net. For more options, visit https://groups.google.com/d/optout.