The answer is here:
http://www.chrisspen.com/blog/handling-postgresql-integrity-errors-in-django.html
I was seeing IntegrityErrors while trying to unit test uniqueness constraints within a database table (it’s not strictly necessary, I suppose, but I was just being thorough, so much for trying to do the right thing):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
$ ./nosetests -v model_tests.py
[...]
======================================================================
ERROR: test_of_some_sort (model_tests.Tests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/lib/python2.7/django/db/models/manager.py", line 149, in create
return self.get_query_set().create(**kwargs)
File "/lib/python2.7/django/db/models/query.py", line 394, in create
obj.save(force_insert=True, using=self.db)
File "/lib/python2.7/django/db/models/base.py", line 537, in save
force_update=force_update, update_fields=update_fields)
File "/lib/python2.7/django/db/models/base.py", line 632, in save_base
result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)
File "/lib/python2.7/django/db/models/manager.py", line 215, in _insert
return insert_query(self.model, objs, fields, **kwargs)
File "/lib/python2.7/django/db/models/query.py", line 1641, in insert_query
return query.get_compiler(using=using).execute_sql(return_id)
File "/lib/python2.7/django/db/models/sql/compiler.py", line 935, in execute_sql
cursor.execute(sql, params)
File "/lib/python2.7/django/db/backends/util.py", line 41, in execute
return self.cursor.execute(sql, params)
File "/lib/python2.7/django/db/backends/postgresql_psycopg2/base.py", line 58, in execute
six.reraise(utils.DatabaseError, utils.DatabaseError(*tuple(e.args)), sys.exc_info()[2])
File "/lib/python2.7/django/db/backends/postgresql_psycopg2/base.py", line 54, in execute
return self.cursor.execute(query, args)
DatabaseError: current transaction is aborted, commands ignored until end of transaction block
|
What didn’t make sense was that the exact same sequences of calls would work just fine in ipython, they just wouldn’t work when under Unit test.
Turns out, whenever an IntegrityError happens while using Django and PostgreSQL, for whatever reason you need to close the entire connection to reset the transaction in the exception handler, which looks like:
1
2
3
4
|
try:
[...]
except IntegrityError:
connection.close()
|