#9269 closed (invalid)
get_or_create having issues
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.0 |
Severity: | Keywords: | get_or_create | |
Cc: | kenkam@…, sholombc@… | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
when i used get_or_create
p, created = Inventory.objects.get_or_create(product = pr, location = lo, storage_type = storagetype) if created: p.amount = amount1 p.save() else: form.save()
it would fail on created, and then it would save the form and make 2 records in the database the second time it would give me a error that it found 2 of the same record
the model and form file: http://dpaste.com/81855/
the product model file: http://dpaste.com/81866/
the view code: http://dpaste.com/81855/
the code that works: http://dpaste.com/81867/
Change History (8)
comment:1 by , 16 years ago
Cc: | added |
---|
comment:2 by , 16 years ago
Description: | modified (diff) |
---|
comment:3 by , 16 years ago
You've got the same link for "the model and form file" and "the view code". It seems to be "the model and form file", so "the view code" is missing.
comment:5 by , 16 years ago
Cc: | added |
---|---|
Resolution: | → invalid |
Status: | new → closed |
Triage Stage: | Unreviewed → Accepted |
p, created = Inventory.objects.get_or_create(product = pr, location = lo, storage_type = storagetype)
executes a query which matches more than one object.
This raises an exception in django/db/models/query.py line 304..
you will either have to:
1.make your get_or_create query more specific by giving more parameters.
2.handle the exception. something like:
try:
p, created = Inventory.objects.get_or_create(product = pr, location = lo, storage_type = storagetype)
except Inventory.MultipleObjectsReturned:
# do something here
for instance, I have reproduced the same error from one of your models:
l1 = Location(name='foo1', description='bar')
l2 = Location(name='foo2', description='bar')
obj, created = Location.objects.get_or_create(description='bar')
l1.save()
l2.save()
obj, created = Location.objects.get_or_create(description='bar')
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python2.5/site-packages/django/db/models/manager.py", line 96, in get_or_create
return self.get_query_set().get_or_create(kwargs)
File "/usr/local/lib/python2.5/site-packages/django/db/models/query.py", line 326, in get_or_create
return self.get(kwargs), False
File "/usr/local/lib/python2.5/site-packages/django/db/models/query.py", line 305, in get
% (self.model._meta.object_name, num, kwargs))
MultipleObjectsReturned: get() returned more than one Location -- it returned 2! Lookup parameters were {'description': 'bar'}
comment:6 by , 16 years ago
Resolution: | invalid |
---|---|
Status: | closed → reopened |
the problem is not that it returns 2 records. the problem is that the first time it doesn't succeed in returning 1 record, which causes it to create a duplicate in the database, but when i do the same lookup a second time it returns 2 records with a error.
p, created = Inventory.objects.get_or_create(product = pr, location = lo, storage_type = storagetype) if created: p.amount = amount1 p.save() else: form.save()
on the first try it will always go to the else: and do form.save() therefor creating a duplicate with the same parameters (product, location,and storage type). instead of changing the amount and saving the record p.save() .
comment:7 by , 16 years ago
Resolution: | → invalid |
---|---|
Status: | reopened → closed |
I think you are misunderstanding how get_or_create()
works. You are saying that it returns with created=False
, which means that the record already existed in the database (and is returned as p
). So then you save another copy. Since there aren't any unique constraints on your model to say it's illegal to save something with duplicate (product, location, storage_type) combinations, the save works and a subsequent filtering will retrieve multiple objects. That's all working as expected.
The second element of the tuple returned from get_or_create()
is only true when a new element is created. It's false if an existing element is retrieved. I can't see that there's any bug here from what you have described. If you're still having trouble understanding that behaviour, perhaps you could construct a shorter example (the current one has a lot of code to wade through) and post a question to django-users to get more help. Trac isn't really useful as a forum for explaining that sort of stuff, however, from your description, things appear to be working as expected.
Reformatted description.