Я использую Django 1.3.1. У меня две базы данных, часть моих моделей живет в одной базе, часть в другой. Обе базы данных являются базами данных contrib.gis.db.backends.postgis.
К моему удивлению, TestCase Django не откатывает изменения, которые я сделал во вторичной базе данных между тестами.
В следующем коде myproject.models.WellOwner представляет собой очень простую модель, которая в основном имеет только поле «имя». Маршрутизатор говорит, что он должен быть во вторичной базе данных. Утверждение в первом тесте завершается успешно, второй тест завершается неудачей :
from django.test import TestCase
from myproject.models import WellOwner
class SimpleTest(TestCase):
def test1(self):
WellOwner.objects.create(name="Remco")
self.assertEquals(1, WellOwner.objects.count()) # Succeeds
class SimpleTest2(TestCase):
def test2(self):
# I would expect to have an empty database at this point
self.assertEquals(0, WellOwner.objects.count()) # Fails!
. Я предполагаю, что Django заключает это в транзакцию в базе данных по умолчанию, но не во вторичной базе данных. Это известная проблема? Есть ли исправление? В 1.4 наверное? Мой гугл -фу не работает.
(если я изменю в настройках БАЗУ ДАННЫХ _МАРШРУТИЗАТОРЫ на [] чтобы все попадало в одну базу, проблема исчезнет)
Я добавлю весь код роутера, вдруг поможет:
SECONDARY_MODELS = ('WellOwner',...)
import logging
logger = logging.getLogger(__name__)
class GmdbRouter(object):
"""Keep some models in a secondary database."""
def db_for_read(self, model, **hints):
if model._meta.app_label == 'gmdb':
if model._meta.object_name in SECONDARY_MODELS:
return 'secondary'
return None
def db_for_write(self, model, **hints):
# Same criteria as for reading
return self.db_for_read(model, **hints)
def allow_syncdb(self, db, model):
if db == 'secondary':
if model._meta.app_label in ('sites', 'south'):
# Hack for bug https://code.djangoproject.com/ticket/16353
# When testing, create django_site and south in both databases
return True
return self.db_for_read(model) == 'secondary'
else:
# Some other db
if model._meta.app_label == 'gmdb':
# Our models go in the other db if they don't go into secondary
return self.db_for_read(model) != 'secondary'
# Some other model in some other db, no opinion
return None