mirror of https://github.com/django/django.git
Fixed #14223 -- Extended unification of exception raised in presence of integrity constraint violations.
The unification had been introduced in r12352 and native backend exceptions still slipped through in cases that end in connection.commit() call. Thanks Alex, Jacob and Carl for reviewing. git-svn-id: http://code.djangoproject.com/svn/django/trunk@14320 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
cad4feabad
commit
cfdad9ed86
|
@ -153,6 +153,13 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
cursor.execute("SET client_encoding to 'UNICODE'")
|
cursor.execute("SET client_encoding to 'UNICODE'")
|
||||||
return UnicodeCursorWrapper(cursor, 'utf-8')
|
return UnicodeCursorWrapper(cursor, 'utf-8')
|
||||||
|
|
||||||
|
def _commit(self):
|
||||||
|
if self.connection is not None:
|
||||||
|
try:
|
||||||
|
return self.connection.commit()
|
||||||
|
except Database.IntegrityError, e:
|
||||||
|
raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
|
||||||
|
|
||||||
def typecast_string(s):
|
def typecast_string(s):
|
||||||
"""
|
"""
|
||||||
Cast all returned strings to unicode strings.
|
Cast all returned strings to unicode strings.
|
||||||
|
|
|
@ -192,3 +192,10 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
finally:
|
finally:
|
||||||
self.isolation_level = level
|
self.isolation_level = level
|
||||||
self.features.uses_savepoints = bool(level)
|
self.features.uses_savepoints = bool(level)
|
||||||
|
|
||||||
|
def _commit(self):
|
||||||
|
if self.connection is not None:
|
||||||
|
try:
|
||||||
|
return self.connection.commit()
|
||||||
|
except Database.IntegrityError, e:
|
||||||
|
raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
from django.contrib.contenttypes import generic
|
from django.contrib.contenttypes import generic
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.conf import settings
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db import connection, DEFAULT_DB_ALIAS
|
from django.db import connection
|
||||||
|
|
||||||
|
|
||||||
class Square(models.Model):
|
class Square(models.Model):
|
||||||
|
@ -55,3 +54,18 @@ class Post(models.Model):
|
||||||
db_table = 'CaseSensitive_Post'
|
db_table = 'CaseSensitive_Post'
|
||||||
|
|
||||||
|
|
||||||
|
class Reporter(models.Model):
|
||||||
|
first_name = models.CharField(max_length=30)
|
||||||
|
last_name = models.CharField(max_length=30)
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return u"%s %s" % (self.first_name, self.last_name)
|
||||||
|
|
||||||
|
|
||||||
|
class Article(models.Model):
|
||||||
|
headline = models.CharField(max_length=100)
|
||||||
|
pub_date = models.DateField()
|
||||||
|
reporter = models.ForeignKey(Reporter)
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return self.headline
|
||||||
|
|
|
@ -2,13 +2,11 @@
|
||||||
# Unit and doctests for specific database backends.
|
# Unit and doctests for specific database backends.
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.core import management
|
|
||||||
from django.core.management.color import no_style
|
from django.core.management.color import no_style
|
||||||
from django.db import backend, connection, connections, DEFAULT_DB_ALIAS
|
from django.db import backend, connection, connections, DEFAULT_DB_ALIAS, IntegrityError
|
||||||
from django.db.backends.signals import connection_created
|
from django.db.backends.signals import connection_created
|
||||||
from django.db.backends.postgresql import version as pg_version
|
from django.db.backends.postgresql import version as pg_version
|
||||||
from django.test import TestCase, skipUnlessDBFeature
|
from django.test import TestCase, skipUnlessDBFeature, TransactionTestCase
|
||||||
from django.utils import unittest
|
from django.utils import unittest
|
||||||
|
|
||||||
from regressiontests.backends import models
|
from regressiontests.backends import models
|
||||||
|
@ -225,3 +223,43 @@ class BackendTestCase(TestCase):
|
||||||
self.assertEqual(list(cursor.fetchmany(2)), [(u'Jane', u'Doe'), (u'John', u'Doe')])
|
self.assertEqual(list(cursor.fetchmany(2)), [(u'Jane', u'Doe'), (u'John', u'Doe')])
|
||||||
self.assertEqual(list(cursor.fetchall()), [(u'Mary', u'Agnelline'), (u'Peter', u'Parker')])
|
self.assertEqual(list(cursor.fetchall()), [(u'Mary', u'Agnelline'), (u'Peter', u'Parker')])
|
||||||
|
|
||||||
|
|
||||||
|
# We don't make these tests conditional because that means we would need to
|
||||||
|
# check and differentiate between:
|
||||||
|
# * MySQL+InnoDB, MySQL+MYISAM (something we currently can't do).
|
||||||
|
# * if sqlite3 (if/once we get #14204 fixed) has referential integrity turned
|
||||||
|
# on or not, something that would be controlled by runtime support and user
|
||||||
|
# preference.
|
||||||
|
# verify if its type is django.database.db.IntegrityError.
|
||||||
|
|
||||||
|
class FkConstraintsTests(TransactionTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
# Create a Reporter.
|
||||||
|
self.r = models.Reporter.objects.create(first_name='John', last_name='Smith')
|
||||||
|
|
||||||
|
def test_integrity_checks_on_creation(self):
|
||||||
|
"""
|
||||||
|
Try to create a model instance that violates a FK constraint. If it
|
||||||
|
fails it should fail with IntegrityError.
|
||||||
|
"""
|
||||||
|
a = models.Article(headline="This is a test", pub_date=datetime.datetime(2005, 7, 27), reporter_id=30)
|
||||||
|
try:
|
||||||
|
a.save()
|
||||||
|
except IntegrityError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_integrity_checks_on_update(self):
|
||||||
|
"""
|
||||||
|
Try to update a model instance introducing a FK constraint violation.
|
||||||
|
If it fails it should fail with IntegrityError.
|
||||||
|
"""
|
||||||
|
# Create an Article.
|
||||||
|
models.Article.objects.create(headline="Test article", pub_date=datetime.datetime(2010, 9, 4), reporter=self.r)
|
||||||
|
# Retrive it from the DB
|
||||||
|
a = models.Article.objects.get(headline="Test article")
|
||||||
|
a.reporter_id = 30
|
||||||
|
try:
|
||||||
|
a.save()
|
||||||
|
except IntegrityError:
|
||||||
|
pass
|
||||||
|
|
Loading…
Reference in New Issue