IntegrityError, how to catch it?

2,696 views
Skip to first unread message

Amit Upadhyay

unread,
Jan 6, 2006, 5:45:25 AM1/6/06
to django-d...@googlegroups.com
Hi,

What is the rigth way of catching IntegrityError, the traceback I get suggests using _mysql_exceptions.IntegrityError, which is wrong because it assumes mysql, as well as it goes against the general python guideline of not using "hidden" members of modules.

Here is my traceback:

>>> u = users.User(id=None, username=' am...@webaroo.com', email='am...@webaroo.com')
>>> u.save()
>>> u2 = users.User(id=None, username='am...@webaroo.com ', email='am...@webaroo.com')
>>> u2.save()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/home/l2g/amitu/DownloadServer/django_src/django/utils/functional.py", line 3, in _curried
    return args[0](*(args[1:]+moreargs), **dict(kwargs.items() + morekwargs.items()))
  File "/home/l2g/amitu/DownloadServer/django_src/django/core/meta/__init__.py", line 1026, in method_save
    ','.join(placeholders)), db_values)
  File "/home/l2g/amitu/DownloadServer/django_src/django/core/db/base.py", line 10, in execute
    result = self.cursor.execute(sql, params)
  File "/home/l2g/amitu/DownloadServer/django_src/django/core/db/backends/mysql.py", line 32, in execute
    return self.cursor.execute(sql, params)
  File "/usr/lib64/python2.4/site-packages/MySQLdb/cursors.py", line 137, in execute
    self.errorhandler(self, exc, value)
  File "/usr/lib64/python2.4/site-packages/MySQLdb/connections.py", line 33, in defaulterrorhandler
    raise errorclass, errorvalue
_mysql_exceptions.IntegrityError: (1062, "Duplicate entry 'am...@webaroo.com' for key 2")
>>>

We should have IntegrityError and other Database error in django.common.errors or django.core.db or something, and different backends should catch database specific ones and throw these, if we are not doing it already.

Thanks,

--
Amit Upadhyay
Blog: http://www.rootshell.be/~upadhyay
+91-9867-359-701

Dody Suria Wijaya

unread,
Jan 6, 2006, 8:17:53 AM1/6/06
to django-d...@googlegroups.com

At the current code, we could only hopes that all database backend
modules fully support Python DB API 2.0, in this case the Exception
tree. I did a simple dir() and looks like MySQLdb, psyopg1, and sqlite3
all support the exceptions, therefore you can reliably catch
IntegrityError exception by wrapping the save() call like this:

from django.core.db import dbmod
try:
u2.save()
except dbmod.Database.IntegrityError:
//handle error
pass

Though, a better way in your case is improving the view code to check
existing user with the same username ahead of time, and rely less on
catching the database exception since not every database trigger the
same exception class on the same error.

David Pratt

unread,
Jan 6, 2006, 10:04:48 AM1/6/06
to django-d...@googlegroups.com
Hi there. What kind of time anticipated time line for no magic branch to
be tagged as a release? I am accumulating a fair amount of code and am
getting nervous about the number of changes that I will need to make
once this is stable.

Many thanks
David

Adrian Holovaty

unread,
Jan 6, 2006, 11:17:19 AM1/6/06
to django-d...@googlegroups.com
On 1/6/06, Amit Upadhyay <upad...@gmail.com> wrote:
> What is the rigth way of catching IntegrityError, the traceback I get
> suggests using _mysql_exceptions.IntegrityError, which is
> wrong because it assumes mysql, as well as it goes against the general
> python guideline of not using "hidden" members of modules.

As Dody Suria Wijaya suggested, you should improve your view code to
validate that the user isn't duplicate. Don't rely on the database to
check things; when using Django, database constraints are just a final
safety layer -- not a high-level source of validation.

Adrian

--
Adrian Holovaty
holovaty.com | djangoproject.com | chicagocrime.org

Amit Upadhyay

unread,
Jan 6, 2006, 11:57:33 AM1/6/06
to django-d...@googlegroups.com
On 1/6/06, Adrian Holovaty <holo...@gmail.com> wrote:

On 1/6/06, Amit Upadhyay <upad...@gmail.com> wrote:
> What is the rigth way of catching IntegrityError, the traceback I get
> suggests using _mysql_exceptions.IntegrityError, which is
> wrong because it assumes mysql, as well as it goes against the general
> python guideline of not using "hidden" members of modules.

As Dody Suria Wijaya suggested, you should improve your view code to
validate that the user isn't duplicate. Don't rely on the database to
check things; when using Django, database constraints are just a final
safety layer -- not a high-level source of validation.

Umm, actually my problem has little to do with validation and more with making sure that I catch all reasonably possible exceptions and handle them appropriately. For example, any IntegrityError is a minor problem, will generate appropriate warning to the user and be done with it, but I want to distinguish this from problems related to failure in talking to the database itself for which I might want to mail my sysadmins, and at last resort I catch Exception [most likely a programming issue] which mails me about the issue for example.

Sorry for using misleading subject if it was.
Reply all
Reply to author
Forward
0 new messages