#20030: django.db.backends.BaseDatabaseWrapper.supports_transactions eats
database
exceptions
----------------------------------------------+--------------------
Reporter: gcc | Owner: nobody
Type: Bug | Status: new
Component: Database layer (models, ORM) | Version: 1.5
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 1
Easy pickings: 0 | UI/UX: 0
----------------------------------------------+--------------------
When there's a problem with the database configuration, running tests can
generate this error:
{{{
======================================================================
ERROR: test_admin_interface_can_view_curriculum
(lessons.tests.LessonsAppTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7
/site-packages/django/test/testcases.py", line 259, in __call__
self._pre_setup()
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/intranet_binder/test_utils.py",
line 205, in _pre_setup
super(AptivateEnhancedTestCase, self)._pre_setup()
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7
/site-packages/django/test/testcases.py", line 479, in _pre_setup
self._fixture_setup()
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7
/site-packages/django/test/testcases.py", line 829, in _fixture_setup
if not connections_support_transactions():
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7
/site-packages/django/test/testcases.py", line 816, in
connections_support_transactions
for conn in connections.all())
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7
/site-packages/django/test/testcases.py", line 816, in <genexpr>
for conn in connections.all())
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7
/site-packages/django/utils/functional.py", line 43, in __get__
res = instance.__dict__[self.func.__name__] = self.func(instance)
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7
/site-packages/django/db/backends/__init__.py", line 455, in
supports_transactions
self.connection.leave_transaction_management()
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7
/site-packages/django/db/backends/__init__.py", line 138, in
leave_transaction_management
"Transaction managed block ended with pending COMMIT/ROLLBACK")
TransactionManagementError: Transaction managed block ended with pending
COMMIT/ROLLBACK
}}}
Which totally hides the nature of the error, which was:
{{{
Traceback (most recent call last):
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7
/site-packages/django/test/testcases.py", line 259, in __call__
self._pre_setup()
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/intranet_binder/test_utils.py",
line 205, in _pre_setup
super(AptivateEnhancedTestCase, self)._pre_setup()
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7
/site-packages/django/test/testcases.py", line 479, in _pre_setup
self._fixture_setup()
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7
/site-packages/django/test/testcases.py", line 829, in _fixture_setup
if not connections_support_transactions():
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7
/site-packages/django/test/testcases.py", line 816, in
connections_support_transactions
for conn in connections.all())
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7
/site-packages/django/test/testcases.py", line 816, in <genexpr>
for conn in connections.all())
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7
/site-packages/django/utils/functional.py", line 43, in __get__
res = instance.__dict__[self.func.__name__] = self.func(instance)
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7
/site-packages/django/db/backends/__init__.py", line 445, in
supports_transactions
cursor.execute('CREATE TABLE ROLLBACK_TEST (X INT)')
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7
/site-packages/django/db/backends/sqlite3/base.py", line 366, in execute
six.reraise(utils.DatabaseError, utils.DatabaseError(*tuple(e.args)),
sys.exc_info()[2])
File
"/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7
/site-packages/django/db/backends/sqlite3/base.py", line 362, in execute
return Database.Cursor.execute(self, query, params)
DatabaseError: attempt to write a readonly database
}}}
The exception thrown by the `finally` clause in `supports_transactions`
obscures the real error by throwing a new one.
I modified `supports_transactions` so that if the `finally` block throws
an exception, it's silently ignored, and the original error is allowed to
propagate upwards, instead of being swallowed by a meaningless one:
{{{
finally:
- self.connection.leave_transaction_management()
+ try:
+ self.connection.leave_transaction_management()
+ except:
+ pass # let the exception propagate upwards
return count == 0
}}}
Maybe we should only do that if the test code actually threw an exception:
{{{
self.connection._dirty = False
+ except:
+ try:
+ self.connection.leave_transaction_management()
+ except:
+ pass # let the exception propagate upwards
+
finally:
self.connection.leave_transaction_management()
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/20030>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.