Django

Code

Changeset 8692

Show
Ignore:
Timestamp:
08/28/08 23:30:07 (3 months ago)
Author:
mtredinnick
Message:

Fixed #8575 -- Catch one particular instance of OperationalError? in MySQL and
convert it to an IntegrityError, which seems like the more natural case (and is
consistent with other backends). This makes exception handling in Django much
easier.

The solution is extensible for any other error codes we may wish to add going
forwards.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/db/backends/mysql/base.py

    r8466 r8692  
    6565# standard util.CursorDebugWrapper can be used. Also, using sql_mode 
    6666# TRADITIONAL will automatically cause most warnings to be treated as errors. 
     67 
     68class CursorWrapper(object): 
     69    """ 
     70    A thin wrapper around MySQLdb's normal cursor class so that we can catch 
     71    particular exception instances and reraise them with the right types. 
     72 
     73    Implemented as a wrapper, rather than a subclass, so that we aren't stuck 
     74    to the particular underlying representation returned by Connection.cursor(). 
     75    """ 
     76    codes_for_integrityerror = (1048,) 
     77 
     78    def __init__(self, cursor): 
     79        self.cursor = cursor 
     80 
     81    def execute(self, query, args=None): 
     82        try: 
     83            return self.cursor.execute(query, args) 
     84        except Database.OperationalError, e: 
     85            # Map some error codes to IntegrityError, since they seem to be 
     86            # misclassified and Django would prefer the more logical place. 
     87            if e[0] in self.codes_for_integrityerror: 
     88                raise Database.IntegrityError(tuple(e)) 
     89            raise 
     90 
     91    def executemany(self, query, args): 
     92        try: 
     93            return self.cursor.executemany(query, args) 
     94        except Database.OperationalError, e: 
     95            # Map some error codes to IntegrityError, since they seem to be 
     96            # misclassified and Django would prefer the more logical place. 
     97            if e[0] in self.codes_for_integrityerror: 
     98                raise Database.IntegrityError(tuple(e)) 
     99            raise 
     100 
     101    def __getattr__(self, attr): 
     102        if attr in self.__dict__: 
     103            return self.__dict__[attr] 
     104        else: 
     105            return getattr(self.cursor, attr) 
     106 
     107    def __iter__(self): 
     108        return iter(self.cursor) 
    67109 
    68110class DatabaseFeatures(BaseDatabaseFeatures): 
     
    208250            kwargs.update(self.options) 
    209251            self.connection = Database.connect(**kwargs) 
    210         cursor = self.connection.cursor(
     252        cursor = CursorWrapper(self.connection.cursor()
    211253        return cursor 
    212254