Opened 14 years ago
Closed 14 years ago
#16340 closed Cleanup/optimization (fixed)
get_or_create should preserve the original traceback.
| Reported by: | Dougal Matthews | Owned by: | Jonas Obrist |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 1.3 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | yes | UI/UX: | no |
Description
(more context in #15117)
get_or_create in django.db.models.query re-raises the last exception as below. This modifies the traceback and the exception should preserve this.
except IntegrityError, e:
transaction.savepoint_rollback(sid, using=self.db)
try:
return self.get(**lookup), False
except self.model.DoesNotExist:
raise e
this can be fixed with
exc_info = sys.exc_info()
try:
return self.get(**lookup), False
except self.model.DoesNotExist:
raise exc_info[1], None, exc_info[2]
Attachments (4)
Change History (9)
by , 14 years ago
| Attachment: | 16340_get_or_create_traceback.patch added |
|---|
by , 14 years ago
| Attachment: | 16340_get_or_create_traceback.2.patch added |
|---|
comment:2 by , 14 years ago
For reference. This patch changes a traceback like this:
Traceback (most recent call last):
File "/vagrant/tests/modeltests/get_or_create/tests.py", line 60, in test_get_or_create
ManualPrimaryKeyTest.objects.get_or_create(id=1, data="Different")
File "/vagrant/django/db/models/manager.py", line 135, in get_or_create
return self.get_query_set().get_or_create(**kwargs)
File "/vagrant/django/db/models/query.py", line 396, in get_or_create
raise e
IntegrityError: PRIMARY KEY must be unique
to show the original full exception traceback:
Traceback (most recent call last):
File "/vagrant/tests/modeltests/get_or_create/tests.py", line 60, in test_get_or_create
ManualPrimaryKeyTest.objects.get_or_create(id=1, data="Different")
File "/vagrant/django/db/models/manager.py", line 135, in get_or_create
return self.get_query_set().get_or_create(**kwargs)
File "/vagrant/django/db/models/query.py", line 386, in get_or_create
obj.save(force_insert=True, using=self.db)
File "/vagrant/django/db/models/base.py", line 463, in save
self.save_base(using=using, force_insert=force_insert, force_update=force_update)
File "/vagrant/django/db/models/base.py", line 556, in save_base
result = manager._insert(values, return_id=update_pk, using=using)
File "/vagrant/django/db/models/manager.py", line 198, in _insert
return insert_query(self.model, values, **kwargs)
File "/vagrant/django/db/models/query.py", line 1459, in insert_query
return query.get_compiler(using=using).execute_sql(return_id)
File "/vagrant/django/db/models/sql/compiler.py", line 810, in execute_sql
cursor = super(SQLInsertCompiler, self).execute_sql(None)
File "/vagrant/django/db/models/sql/compiler.py", line 754, in execute_sql
cursor.execute(sql, params)
File "/vagrant/django/db/backends/sqlite3/base.py", line 226, in execute
return Database.Cursor.execute(self, query, params)
IntegrityError: PRIMARY KEY must be unique
comment:3 by , 14 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
by , 14 years ago
| Attachment: | 16340_get_or_create_traceback.3.patch added |
|---|
comment:4 by , 14 years ago
| Owner: | changed from to |
|---|
Updated the patch to apply to trunk.
Also made use of the new unittest2 features (namely assertIn).
https://github.com/ojii/django/compare/django:master...ojii:16340
by , 14 years ago
| Attachment: | 16340.patch added |
|---|
new patch (same as https://github.com/ojii/django/compare/django:master...ojii:16340)
Added a patch that preserves the original traceback with a test. The test isn't ideal since we need to check the contents of a traceback, but it looks for the save call since this is where the IntegrityError comes from (in other words its the safest thing we can bet on being there.)
(Trac added the upload twice for some reason?)