Opened 4 years ago

Closed 4 years ago

#16948 closed Uncategorized (duplicate)

Django DB backends hid information in database exceptions

Reported by: jamesh Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Normal Keywords:
Cc: jamesh Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

The Django DB backends replace the exceptions raised by the underlying adapter with standard ones from django.db.utils.

I understand the reason for doing this (provide standard exceptions that calling code can catch), but it can lose information provided by those exceptions. For example, the psycopg2 adapter exposes the SQL error code as a "code" attribute on exceptions, and this is lost.

Perhaps using the same strategy as Storm would help: rather than catching the adapter's exceptions and re-raising equivalent standard ones, it patches the adapter's exceptions so that they subclass from the standard ones. This could be done with a method like the following:

def install_exceptions(module):
    if not isinstance(module.DatabaseError, django.db.utils.DatabaseError):
        module.DatabaseError.__bases__ += (django.db.utils.DatabaseError,)
    if not isinstance(module.IntegrityError, django.db.utils.IntegrityError):
        module.IntegrityError.__bases__ += (django.db.utils.IntegrityError,)

Once the adapter's exceptions have been patched it would no longer be necessary to wrap the adapter's cursors, since the standard cursor would raise exceptions that could be caught by generic code.

Attachments (1)

db-backend-exceptions.patch (6.8 KB) - added by jamesh 4 years ago.
Sample implementation of idea for the postgresql, mysql and sqlite backends.

Download all attachments as: .zip

Change History (6)

comment:1 Changed 4 years ago by jamesh

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

and of course, I meant issubclass() rather than isinstance() in the code snippet in the initial comment.

comment:2 Changed 4 years ago by ptone

  • Triage Stage changed from Unreviewed to Accepted
  • Type changed from Uncategorized to Cleanup/optimization

possible related tickets:

#8740

and more relevant would be #15901

But neither seem to be duplicates WRT the notion of passing on specific error codes, which could be useful in debugging

comment:3 Changed 4 years ago by jamesh

  • Triage Stage changed from Accepted to Unreviewed
  • Type changed from Cleanup/optimization to Uncategorized

I guess you could consider this a duplicate of the underlying idea of #15901. In both cases, we want access to more information about errors than is present in Django's limited database independent API.

The other bug proposes to fix problem by extending the database independent API. This bug proposes to fix it by not interfering with the adapter's exceptions but making them conform to the existing database independent API.

Changed 4 years ago by jamesh

Sample implementation of idea for the postgresql, mysql and sqlite backends.

comment:4 Changed 4 years ago by jamesh

  • Has patch set

comment:5 Changed 4 years ago by Alex

  • Resolution set to duplicate
  • Status changed from new to closed

Marking as a dupe of #15901

Note: See TracTickets for help on using tickets.
Back to Top