#30053: Allow for conditional QuerySet.update_or_create()
-------------------------------------+-------------------------------------
Reporter: Joshua Cannon | Owner: Nasir
| Hussain
Type: New feature | Status: assigned
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: QuerySet | Triage Stage:
update_or_create | Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Nasir Hussain):
Hi,
The feature requested has the following cases if the update condition is
provided:
1. No objects matching foo=bar -> Create a new object
2. Object matching foo=bar but doesn't satisfy the condition -> do
nothing.
3. Object matching foo=bar and satisfy the condition -> update the object.
In the code below If there is an object foo=bar and doesn't satisfy
condition date__lt=minimal the object foo=bar will still get updated.
{{{#!python
with transaction.atomic():
# .update() returns the number of updated rows.
if not objects.filter(foo=bar, date__lt=minimal).update(**defaults):
# Either the row doesn't exist or doesn't match the optimistic
condition
objects.update_or_create(foo=bar, default=defaults)
}}}
What we usually do is:
{{{#!python
with transaction.atomic():
# .update() returns the number of updated rows.
if not objects.filter(foo=bar, date__lt=minimal).update(**defaults)
and not objects.filter(foo=bar).exists():
# Either the row doesn't exist or doesn't match the optimistic
condition
objects.create
}}}
Which leads to 3 different queries to database.1st for the update, 2nd for
exists and 3rd to save.
If we add an update condition parameter, the same could be achieved in 2
queries.
Replying to [comment:9 Simon Charette]:
> Hello there,
>
> In order to avoid wasted efforts I'd suggest you try to gather consensus
on the mailing list about whether or not this feature might be useful to
other developers before commiting time to a final implementation. A PR can
certainly help in backing up backward compatiblity and implementation
claims but since this complexifies an already complex method I'd be great
to confirm it's a desired feature first. It's also a great opportunity to
get implementation feedback or identify a larger issue.
>
> I'm personally not sold on the feature addition because it looks like it
could be implemented with a prior `update` query and accepting a
conditional callable to ''match'' a model instances is not a pattern used
anywhere else.
>
> e.g
>
> {{{#!python
>
> with transaction.atomic():
> # .update() returns the number of updated rows.
> if not objects.filter(foo=bar, date__lt=minimal).update(**defaults):
> # Either the row doesn't exist or doesn't match the optimistic
condition
> objects.update_or_create(foo=bar, default=defaults)
> }}}
--
Ticket URL: <https://code.djangoproject.com/ticket/30053#comment:10>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/068.15ff357985d36986b2b6535fabee0bf5%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.