Django TestCase no usa transacciones en base de datos secundaria
Estoy usando Django 1.3.1. Tengo dos bases de datos, algunos de mis modelos viven en una base de datos, otros en la otra. Ambas bases de datos son bases de datos contrib.gis.db.backends.postgis.
Para mi sorpresa, el TestCase de Django no está haciendo retroceder los cambios que hice en la base de datos secundaria entre pruebas.
En el siguiente código, myproject.models.WellOwner es un modelo muy simple que básicamente solo tiene un campo "nombre". El enrutador dice que debería estar en la base de datos secundaria. La afirmación en la primera prueba tiene éxito, la segunda prueba falla:
<code>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! </code>
Supongo que Django envuelve esto en una transacción en la base de datos predeterminada, pero no en la base de datos secundaria. ¿Es este un problema conocido? ¿Hay alguna solución? En 1.4 tal vez? Mi Google-fu está fallando.
(Si cambio DATABASE_ROUTERS a [] en la configuración para que todo entre en la misma base de datos, el problema desaparece)
Agregaré el código completo del enrutador, en caso de que ayude:
<code>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 </code>