Opened 8 years ago
Closed 8 years ago
#27288 closed Uncategorized (invalid)
In multi-db setup changes written to master are not seen on read-replicas
Reported by: | Jose M Herrero | Owned by: | nobody |
---|---|---|---|
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.
I'm following documentation at https://docs.djangoproject.com/es/1.10/topics/db/multi-db/ and https://docs.djangoproject.com/en/1.10/topics/testing/advanced/#tests-and-multiple-databases
A simple test writing and reading back the object fails. (I have used a user with write permissions to avoid problem #27286)
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 mysite
and cd into itcd mysite
- Create a database router
mysite/dbrouter.py
Code 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.py
with 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', 'PASSWORD': 'mypassword', 'HOST': '127.0.0.1', 'PORT': '', 'TEST': { 'MIRROR': 'default', }, }, } DATABASE_ROUTERS = ['mysite.dbrouter.DbRouter']
- Create
mysite/tests.py
Code highlighting:
from django.test import TestCase from django.contrib.auth.models import User class SurveyFormTest(TestCase): def setUp(self): self.user = User.objects.create_user('username') def test_sample(self): self.assertEqual(User.objects.count(), 1)
- Execute the tests and bang!
python manage.py test mysite
Creating test database for alias 'default'... F ====================================================================== FAIL: test_sample (mysite.tests.SurveyFormTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/chemary/workspace/myvirtualenv/mysite/mysite/tests.py", line 9, in test_sample self.assertEqual(User.objects.count(), 1) AssertionError: 0 != 1 ---------------------------------------------------------------------- Ran 1 test in 0.111s FAILED (failures=1) Destroying test database for alias 'default'...
Change History (2)
comment:2 by , 8 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
It looks like you didn't set the multi_db attribute on your test case class.
Please don't use the ticket system as a support channel, see TicketClosingReasons/UseSupportChannels.
Using
TransactionTestCase
solves the problem, maybe multi-db in tests is only intended to test that replication configuration works and not the whole set of tests?