Fixed #16340 -- Made `get_or_create()` re-raise any `IntegrityError` with its original traceback. Thanks to d0ugal and Jonas Obrist.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@17333 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
fc9e0606d5
commit
31b1cbc623
|
@ -4,6 +4,7 @@ The main QuerySet implementation. This provides the public API for the ORM.
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import itertools
|
import itertools
|
||||||
|
import sys
|
||||||
|
|
||||||
from django.db import connections, router, transaction, IntegrityError
|
from django.db import connections, router, transaction, IntegrityError
|
||||||
from django.db.models.fields import AutoField
|
from django.db.models.fields import AutoField
|
||||||
|
@ -450,10 +451,12 @@ class QuerySet(object):
|
||||||
return obj, True
|
return obj, True
|
||||||
except IntegrityError, e:
|
except IntegrityError, e:
|
||||||
transaction.savepoint_rollback(sid, using=self.db)
|
transaction.savepoint_rollback(sid, using=self.db)
|
||||||
|
exc_info = sys.exc_info()
|
||||||
try:
|
try:
|
||||||
return self.get(**lookup), False
|
return self.get(**lookup), False
|
||||||
except self.model.DoesNotExist:
|
except self.model.DoesNotExist:
|
||||||
raise e
|
# Re-raise the IntegrityError with its original traceback.
|
||||||
|
raise exc_info[1], None, exc_info[2]
|
||||||
|
|
||||||
def latest(self, field_name=None):
|
def latest(self, field_name=None):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
import traceback
|
||||||
|
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
@ -52,3 +53,14 @@ class GetOrCreateTests(TestCase):
|
||||||
ManualPrimaryKeyTest.objects.get_or_create, id=1, data="Different"
|
ManualPrimaryKeyTest.objects.get_or_create, id=1, data="Different"
|
||||||
)
|
)
|
||||||
self.assertEqual(ManualPrimaryKeyTest.objects.get(id=1).data, "Original")
|
self.assertEqual(ManualPrimaryKeyTest.objects.get(id=1).data, "Original")
|
||||||
|
|
||||||
|
# get_or_create should raise IntegrityErrors with the full traceback.
|
||||||
|
# This is tested by checking that a known method call is in the traceback.
|
||||||
|
# We cannot use assertRaises/assertRaises here because we need to inspect
|
||||||
|
# the actual traceback. Refs #16340.
|
||||||
|
try:
|
||||||
|
ManualPrimaryKeyTest.objects.get_or_create(id=1, data="Different")
|
||||||
|
except IntegrityError, e:
|
||||||
|
formatted_traceback = traceback.format_exc()
|
||||||
|
self.assertIn('obj.save', formatted_traceback)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue