2012-04-12 1 views
7

Я использую Django 1.3.1. У меня две базы данных, некоторые из моих моделей живут в одной базе данных, некоторые - в другой. Обе базы данных представляют собой базы данных contrib.gis.db.backends.postgis.Django TestCase не использует транзакции во вторичной базе данных

К моему удивлению, 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 возможно? Мой Google-fu не работает.

(если я изменю DATABASE_ROUTERS на [] в настройках, так что все идет в ту же базу данных, то проблема исчезает)

Я добавлю весь код маршрутизатора, в случае, если это помогает:

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 
+0

Вам необходимо включить маршрутизаторы в вопросе. Вот в чем проблема. –

+0

У меня есть аналогичный случай, когда исправление 'connection._rollback()' для 'integrityerror' больше не работает, как только я перемещаю модель в отдельную базу данных. Также модели postgis, так что, возможно, что-то не так в 'django.contrib.gis.db.models' – RickyA

+0

эй RemcoGerlich, вы когда-нибудь находили разрешение? Я борюсь с той же проблемой http://stackoverflow.com/questions/12205855/factory-boy-instance-within-testcase-causes-unique-contraint-violation –

ответ