Opened 9 years ago
Closed 9 years ago
#27286 closed Bug (duplicate)
Tests fail on MySQL when using multi-db and some DB is read-only due to supports_transactions() call
| Reported by: | Jose M Herrero | Owned by: | Mariusz Felisiak |
|---|---|---|---|
| Component: | Testing framework | Version: | 1.10 |
| Severity: | Normal | Keywords: | multi-db dbrouter |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
I'm triying to implement a multi-db platform with one master and some read-replicas, I wanted to reflect this structure also in tests. When I run tests they try to write to read only databases although router is configured to not allow it.
To reproduce with nothing interfering I started a fresh project, these are the steps to reproduce:
- Start a new Django 1.10.1 project with
django-admin startproject mysiteand cd into itcd mysite - Create a database router
mysite/dbrouter.pyCode highlighting:
class DbRouter(object): def db_for_read(self, model, **hints): return 'read_replica' def db_for_write(self, model, **hints): return 'default' def allow_relation(self, obj1, obj2, **hints): return True def allow_migrate(self, db, app_label, model_name=None, **hints): if db == 'read_replica': return False return True
- Edit
mysite.settings.pywith master and read databases and set the database router
Code highlighting:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mysite', 'USER': 'myuser', 'PASSWORD': 'mypassword', 'HOST': '127.0.0.1', 'PORT': '', }, 'read_replica': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mysite', 'USER': 'myuser_read', 'PASSWORD': 'myreadpassword', 'HOST': '127.0.0.1', 'PORT': '', }, } DATABASE_ROUTERS = ['mysite.dbrouter.DbRouter']
- Create
mysite/tests.pyCode highlighting:
from django.test import TestCase class SurveyFormTest(TestCase): def test_sample(self): print 'hello'
- Execute the tests and bang!
python manage.py test mysite
Creating test database for alias 'default'...
E
======================================================================
ERROR: setUpClass (mysite.tests.SurveyFormTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-packages/django/test/testcases.py", line 1009, in setUpClass
if not connections_support_transactions():
File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-packages/django/test/testcases.py", line 974, in connections_support_transactions
for conn in connections.all())
File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-packages/django/test/testcases.py", line 974, in <genexpr>
for conn in connections.all())
File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-packages/django/db/backends/base/features.py", line 235, in supports_transactions
cursor.execute('CREATE TABLE ROLLBACK_TEST (X INT)')
File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-packages/django/db/utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 62, in execute
return self.cursor.execute(sql)
File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 112, in execute
return self.cursor.execute(query, args)
File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-packages/MySQLdb/cursors.py", line 205, in execute
self.errorhandler(self, exc, value)
File "/home/chemary/workspace/myvirtualenv/local/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
OperationalError: (1142, "CREATE command denied to user 'myuser_read'@'localhost' for table 'ROLLBACK_TEST'")
----------------------------------------------------------------------
Ran 0 tests in 0.026s
FAILED (errors=1)
Destroying test database for alias 'default'...
Change History (5)
comment:1 by , 9 years ago
follow-up: 3 comment:2 by , 9 years ago
Do you have any ideas about how we could detect whether or not the database supports transactions besides the current algorithm that requires creating a table?
comment:3 by , 9 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:4 by , 9 years ago
New algorithm for mySQL that determines whether the database supports transactions, instead of CREATE TABLE... test PR
comment:5 by , 9 years ago
| Resolution: | → duplicate |
|---|---|
| Status: | assigned → closed |
| Summary: | Tests fails when using multi-db and some DB is read-only → Tests fail on MySQL when using multi-db and some DB is read-only due to supports_transactions() call |
Duplicate of #26541
I have tried to add configuration mentioned here but the error is the same
https://docs.djangoproject.com/en/1.10/topics/testing/advanced/#tests-and-multiple-databases