﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
14223	Inconsistent exception raising on DB integrity errors	Ramiro Morales	Ramiro Morales	"It seems we aren't capturing the `<db api driver module>.IntegrityError` exceptions raised when `connection.commit() is executed` in the same way we do in `execute()`.

Found this while creating tests to verify FK constraint in sqlite (#14204). My `assertRaises(django.db.[utils.]IntegrityError, ...)` weren't being triggered and printing the exception type shows `<class 'pysqlite2.dbapi2.IntegrityError'>`. Same thing happens now with postgres (see below).

The `DatabaseError` and `IntegrityError` unification was introduced in r12352, if this is confirmed as an issue it wouldn't be a regression in 1.2, but a 1.2 feature introduced in an incomplete fashion.

The two files pasted at the end form a small test case. When run under postgres you see:

{{{
======================================================================
ERROR: Try to create a model instance that violates a FK constraint. Should fail
----------------------------------------------------------------------
Traceback (most recent call last):
  File ""/home/r/django/sqlite_fk2/tests/regressiontests/fk_constraints/tests.py"", line 22, in test_integrity_checks_on_creation
    a.save()
  File ""/home/r/django/sqlite_fk2/django/db/models/base.py"", line 434, in save
    self.save_base(using=using, force_insert=force_insert, force_update=force_update)
  File ""/home/r/django/sqlite_fk2/django/db/models/base.py"", line 534, in save_base
    transaction.commit_unless_managed(using=using)
  File ""/home/r/django/sqlite_fk2/django/db/transaction.py"", line 175, in commit_unless_managed
    connection._commit()
  File ""/home/r/django/sqlite_fk2/django/db/backends/__init__.py"", line 32, in _commit
    return self.connection.commit()
IntegrityError: insert or update on table ""fk_constraints_article"" violates foreign key constraint ""fk_constraints_article_reporter_id_fkey""
DETAIL:  Key (reporter_id)=(30) is not present in table ""fk_constraints_reporter"".

<class 'psycopg2.IntegrityError'>
}}}

{{{
#!python
# models.py
from django.db import models

class Reporter(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    email = models.EmailField()

    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

    class Meta:
        ordering = ('headline',)
}}}

{{{
#!python
# tests.py
from datetime import datetime

from django.db import utils
from django.test import TransactionTestCase

from models import Reporter, Article

import sys

class FkConstraintsTest(TransactionTestCase):

    def setUp(self):
        # Create a Reporter.
        self.r = Reporter.objects.create(first_name='John', last_name='Smith', email='john@example.com')
        #self.r2 = Reporterobjects.create(first_name='Paul', last_name='Jones', email='paul@example.com')

    def test_integrity_checks_on_creation(self):
        """"""Try to create a model instance that violates a FK constraint. Should fail""""""
        a = Article(headline=""This is a test"", pub_date=datetime(2005, 7, 27), reporter_id=30)
        #self.assertRaises(utils.IntegrityError, a.save)
        try:
            a.save()
        except Exception, e:
            print >>sys.stderr, type(e)
            raise

    def test_integrity_checks_on_update(self):
        """"""Try to update a model instance introducing a FK constraint violation. Should fail""""""
        # Create an Article.
        Article.objects.create(headline=""Test article"", pub_date=datetime(2010, 9, 4), reporter=self.r)
        # Retrive it from the DB
        a = Article.objects.get(headline=""Test article"")
        a.reporter_id = 30
        #self.assertRaises(utils.IntegrityError, a.save)
        try:
            a.save()
        except Exception, e:
            print >>sys.stderr, type(e)
            raise
}}}
"		closed	Database layer (models, ORM)	dev		fixed	integrityerror backends orm		Accepted	1	0	0	0	0	0
