Тест Django с несколькими базами данных без подключения по умолчанию
Я создал урезанный сценарий с нуля, чтобы надеяться найти решение того, что я наблюдал в некотором производственном коде - который остановил меня на полпути.
Код находится здесь:
https://github.com/andez2000/issue-django-multi-db
Проблема в том, что у меня есть проект Django - который будет поддерживать несколько баз данных. Так что для этого сценария:
- acmeapp нацелен на acmeapp_db.
- auth нацелен на auth_db.
- Нет соединения по умолчанию - все соединения являются псевдослучайными.
Это не является прямым результатом просмотра следующего: https://www.youtube.com/watch?v=GBgRMdjAx_c. https://www.youtube.com/watch?v=GBgRMdjAx_c
Роутеры были установлены и настроены для направления моделей к соединениям.
При запуске py manage.py test
проявляются следующие ошибки.
AssertionError: Database queries to 'acmeapp_db' are not allowed in this test. Add 'acmeapp_db' to acmeapp.tests.model.TestModels.databases to ensure proper test isolation and silence this failure.
Исправление этого, как было предложено, приводит к дополнительной ошибке:
ImproperlyConfigured("Circular dependency in TEST[DEPENDENCIES]") django.core.exceptions.ImproperlyConfigured: Circular dependency in TEST[DEPENDENCIES]
core/settings.py
DATABASES = {
'default': {},
'auth_db': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'auth_db.sqlite3',
"TEST": {"NAME": "auth_db"},
#'SUPPORTS_TRANSACTIONS': True,
},
'acmeapp_db': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'acmeapp_db.sqlite3',
"TEST": {"NAME": "acmeapp_db"},
#'SUPPORTS_TRANSACTIONS': True,
}
}
DATABASE_ROUTERS = [
'core.db_routers.AuthRouter',
'core.db_routers.AcmeAppRouter'
]
tests/model.py
from django.test import TestCase
from acmeapp.models import Post
class TestModels(TestCase):
def setUp(self):
Post.objects.create(title="This is a test")
def test_Post_str(self):
post = Post.objects.first()
self.assertEqual(str(post), "This is a test")
core/db_routers.py
class AuthRouter:
route_app_labels = ['auth', 'contenttypes', 'sessions', 'admin']
def db_for_read(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return 'auth_db'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return 'auth_db'
return None
def allow_relation(self, obj1, obj2, **hints):
if (
obj1._meta.app_label in self.route_app_labels or
obj2._meta.app_label in self.route_app_labels
):
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label in self.route_app_labels:
return db == 'auth_db'
return None
class AcmeAppRouter:
route_app_labels = ['acmeapp']
def db_for_read(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return 'acmeapp_db'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return 'acmeapp_db'
return None
def allow_relation(self, obj1, obj2, **hints):
if (
obj1._meta.app_label in self.route_app_labels or
obj2._meta.app_label in self.route_app_labels
):
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label in self.route_app_labels:
return db == 'acmeapp_db'
return None
Отладка маршрутизаторов - псевдоним базы данных в параметре db
всегда 'default'
.
Возможна ли вообще такая установка? Я что-то упускаю?