[Django] #29733: update_or_create - documentation misleading

26 views
Skip to first unread message

Django

unread,
Sep 4, 2018, 7:00:31 AM9/4/18
to django-...@googlegroups.com
#29733: update_or_create - documentation misleading
------------------------------------------------+------------------------
Reporter: DavidPratten | Owner: nobody
Type: Cleanup/optimization | Status: new
Component: Documentation | Version: 2.1
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
------------------------------------------------+------------------------
When update_or_create searches the table for a record to update it
searches all fields marked 'unique' or 'primary_key'.

In the case where a record has two candidate keys the update_or_create
function will fail to update either the primary key or the candidate key,
leading to an Integrity Error.

https://docs.djangoproject.com/en/2.1/ref/models/querysets/#update-or-
create

This behavour is not 'wrong'. But it is surprising and a time waster.

{{{
class Coa(models.Model):
def __str__(self):
return f'{self.qbac}'
trantype = models.CharField(max_length=255, db_column=u'TranType',
blank=True)
qbac = models.CharField( unique=True, max_length=255,
db_column=u'QBAc')
guid = models.CharField(max_length=32, primary_key=True)
account_type=models.CharField(max_length=20)
}}}

Containing the following record:
{{{
"ACCNT", "Advantage Saver", "c6f30c15c9dd1e5af9143fd7bed99315", "A"
}}}

The following, otherwise sensible, code fails with an IntegrityError

{{{
obj, created =
Coa.objects.update_or_create(guid='c6f30c15c9dd1e5af9143fd7bed99315',
defaults={'trantype': 'ACCNT', 'qbac': 'A', 'account_type': 'A' },)
}}}

because the search is on both guid AND qbac rather than just on guid as
requested by the single field in the !**kwargs.

Recommend clarification in the docu that it is not possible to search only
on one field if there are multiple unique constraints in the model.

David

--
Ticket URL: <https://code.djangoproject.com/ticket/29733>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Sep 4, 2018, 4:24:39 PM9/4/18
to django-...@googlegroups.com
#29733: update_or_create - documentation misleading
-------------------------------------+-------------------------------------
Reporter: David Pratten | Owner: nobody
Type: | Status: new
Cleanup/optimization |
Component: Documentation | Version: 2.1
Severity: Normal | Resolution:

Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Alexander Holmbäck):

Hi David,

I can't replicate this behavior and the update works as expected. Make
sure that there isn't another record where the value of qbac is set to 'A'
(in case an IntegrityError is rightfully raised), if the problem persist,
please provide the message and stacktrace of your error so that I can test
this further.

--
Ticket URL: <https://code.djangoproject.com/ticket/29733#comment:1>

Django

unread,
Sep 5, 2018, 3:34:57 AM9/5/18
to django-...@googlegroups.com
#29733: update_or_create - documentation misleading
-------------------------------------+-------------------------------------
Reporter: David Pratten | Owner: nobody
Type: | Status: closed
Cleanup/optimization |
Component: Documentation | Version: 2.1
Severity: Normal | Resolution: invalid

Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Carlton Gibson):

* status: new => closed
* resolution: => invalid


Comment:

Adding the following to the `UpdateOrCreateTests` (in
[https://github.com/django/django/tree/master/tests/get_or_create
`get_or_create` module] does not produce a failure:

{{{
def test_29733(self):
p = Person.objects.create(
first_name='John', last_name='Lennon', birthday=date(1940, 10,
9)
)
p, created = Person.objects.update_or_create(
pk=p.pk, defaults={
'first_name':'John',
}
)
self.assertFalse(created)
}}}

The `Person` model is unique on the primary key and `first_name` fields.
(So AFAICS it should be a test case for your example.)

As such I'm going to close this as invalid. If you can provide a failing
test case I'm happy to re-open.

--
Ticket URL: <https://code.djangoproject.com/ticket/29733#comment:2>

Reply all
Reply to author
Forward
0 new messages