Opened 10 years ago

Closed 9 years ago

#22279 closed Bug (fixed)

AttributeError: 'db.backends.dummy.base.DatabaseWrapper' object has no attribute 'Database'

Reported by: Daniel Hahler Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I am getting a AttributeError: 'DatabaseWrapper' object has no attribute 'Database' exception, while trying to setup/use py.test with Django.

DJANGO_SECRET_KEY=foo DJANGO_SETTINGS_MODULE=config.settings PYTHONPATH=. py.test -s --ipdb project/model/tests.py

self.wrapper is django.db.backends.dummy.base.DatabaseWrapper.

> …/django-master/django/db/utils.py(86)__exit__()
     85         ):
---> 86             db_exc_type = getattr(self.wrapper.Database, dj_exc_type.__name__)
     87             if issubclass(exc_type, db_exc_type):

ipdb> bt
  …/django-master/django/test/testcases.py(857)<genexpr>()
    855     """
    856     return all(conn.features.supports_transactions
--> 857                for conn in connections.all())
    858 
    859 

  …/django-master/django/utils/functional.py(55)__get__()
     53         if instance is None:
     54             return self
---> 55         res = instance.__dict__[self.func.__name__] = self.func(instance)
     56         return res
     57 

  …/django-master/django/db/backends/__init__.py(701)supports_transactions()
    699                 self.connection.commit()
    700         finally:
--> 701             self.connection.leave_transaction_management()
    702         return count == 0
    703 

  …/django-master/django/db/backends/__init__.py(320)leave_transaction_management()
    318                 "Transaction managed block ended with pending COMMIT/ROLLBACK")
    319 
--> 320         if managed == self.get_autocommit():
    321             self.set_autocommit(not managed)
    322 

  …/django-master/django/db/backends/__init__.py(327)get_autocommit()
    325         Check the autocommit state.
    326         """
--> 327         self.ensure_connection()
    328         return self.autocommit
    329 

  …/django-master/django/db/backends/__init__.py(124)ensure_connection()
    122         if self.connection is None:
    123             with self.wrap_database_errors:
--> 124                 self.connect()
    125 
    126     ##### Backend-specific wrappers for PEP-249 connection methods #####

> …/django-master/django/db/utils.py(86)__exit__()
     84                 Error,
     85         ):
---> 86             db_exc_type = getattr(self.wrapper.Database, dj_exc_type.__name__)
     87             if issubclass(exc_type, db_exc_type):
     88                 dj_exc_value = dj_exc_type(*exc_value.args)

  …/django-master/django/test/testcases.py(182)__call__()
    180         if not skipped:
    181             try:
--> 182                 self._pre_setup()
    183             except Exception:
    184                 result.addError(self, sys.exc_info())

  …/django-master/django/test/testcases.py(749)_pre_setup()
    747                 flush.Command.emit_post_migrate(verbosity=0, interactive=False, database=db_name)
    748         try:
--> 749             self._fixture_setup()
    750         except Exception:
    751             if self.available_apps is not None:

  …/django-master/django/test/testcases.py(870)_fixture_setup()
    868 
    869     def _fixture_setup(self):
--> 870         if not connections_support_transactions():
    871             return super(TestCase, self)._fixture_setup()
    872 

  …/django-master/django/test/testcases.py(857)connections_support_transactions()
    855     """
    856     return all(conn.features.supports_transactions
--> 857                for conn in connections.all())
    858 
    859 

  …/django-master/django/test/testcases.py(857)<genexpr>()
    855     """
    856     return all(conn.features.supports_transactions
--> 857                for conn in connections.all())
    858 
    859 

  …/django-master/django/utils/functional.py(55)__get__()
     53         if instance is None:
     54             return self
---> 55         res = instance.__dict__[self.func.__name__] = self.func(instance)
     56         return res
     57 

  …/django-master/django/db/backends/__init__.py(701)supports_transactions()
    699                 self.connection.commit()
    700         finally:
--> 701             self.connection.leave_transaction_management()
    702         return count == 0
    703 

  …/django-master/django/db/backends/__init__.py(320)leave_transaction_management()
    318                 "Transaction managed block ended with pending COMMIT/ROLLBACK")
    319 
--> 320         if managed == self.get_autocommit():
    321             self.set_autocommit(not managed)
    322 

  …/django-master/django/db/backends/__init__.py(327)get_autocommit()
    325         Check the autocommit state.
    326         """
--> 327         self.ensure_connection()
    328         return self.autocommit
    329 

  …/django-master/django/db/backends/__init__.py(124)ensure_connection()
    122         if self.connection is None:
    123             with self.wrap_database_errors:
--> 124                 self.connect()
    125 
    126     ##### Backend-specific wrappers for PEP-249 connection methods #####

> …/django-master/django/db/utils.py(86)__exit__()
     84                 Error,
     85         ):
---> 86             db_exc_type = getattr(self.wrapper.Database, dj_exc_type.__name__)
     87             if issubclass(exc_type, db_exc_type):
     88                 dj_exc_value = dj_exc_type(*exc_value.args)

Change History (8)

comment:1 by Tim Graham, 10 years ago

Resolution: needsinfo
Status: newclosed

It's not clear to me that this is a bug in Django, or if it is, how we can reproduce it. More likely, you should first use our support channels to see if others have been able to use py.test with Django. A quick search reveals pytest-django which suggests others have been able successfully integrate the two projects.

https://code.djangoproject.com/wiki/TicketClosingReasons/UseSupportChannels

comment:2 by Daniel Hahler, 10 years ago

Resolution: needsinfo
Status: closednew

I am using pytest-django already.

The problem gets triggered, because DATABASES is empty and therefore the dummy database is used.

From DatabaseErrorWrapper:

It must have a Database attribute defining PEP-249 exceptions.

class DatabaseErrorWrapper(object):
    """
    Context manager and decorator that re-throws backend-specific database
    exceptions using Django's common wrappers.
    """

    def __init__(self, wrapper):
        """
        wrapper is a database wrapper.

        It must have a Database attribute defining PEP-249 exceptions.
        """
        self.wrapper = wrapper

comment:3 by Tim Graham, 10 years ago

Thanks for the additional info. Can you provide a test case for Django's test suite that isn't dependent on py.test (or at least a sample project we can use to reproduce the error)? Is this a regression on master for something that worked with Django 1.6?

comment:4 by Daniel Hahler, 10 years ago

It's rather trivial: create a new project, an app, add a model and tests that use the model (and therefore the database).
Then remove the DATABASES setting, and run the tests.

This is constructed, of course, but I've run into this when DATABASES was not setup correctly by accident - and the error could have been friendlier.

Again, I think that the dummy backend has to provide the Database attribute required by DatabaseErrorWrapper - or it must never get wrapped in the first place (if that's an option).

comment:5 by Aymeric Augustin, 10 years ago

Triage Stage: UnreviewedAccepted

comment:6 by Claude Paroz, 9 years ago

Has patch: set

comment:7 by Tim Graham, 9 years ago

Triage Stage: AcceptedReady for checkin

comment:8 by Claude Paroz <claude@…>, 9 years ago

Resolution: fixed
Status: newclosed

In 3c5d1edb39020f549c58e0696b8ab2f03a88d753:

Fixed #22279 -- Prevented dummy backend going through DatabaseErrorWrapper

Thanks Daniel Hahler for the report and Tim Graham for the review.

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