Django TestCase not using transactions on secondary database
django, multiple-databases, python
Solution
Try this:
class MyTestCase(TestCase):
multi_db = True
https://docs.djangoproject.com/en/1.2/topics/testing/#django.test.TestCase.multi_db
Problem
I am using Django 1.3.1. I have two databases, some of my models live in one database, some in the other. Both databases are contrib.gis.db.backends.postgis databases. To my surprise, Django's TestCase isn't rolling back changes I made in the secondary database between tests. In the following code, myproject.models.WellOwner is a very simple model that basically only has a field "name". The router says that it should be in the secondary database. The assertion in the first test succeeds, the second test fails: ``` 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! ``` I assume that Django wraps this in a transaction on the default database, but not on the secondary database. Is this a known problem? Is there a fix? In 1.4 perhaps? My Google-fu is failing. (if I change DATABASE_ROUTERS to [] in settings so that everything goes into the same database, the problem disappears) I'll add the whole code of the router, in case it helps: ``` 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 ```