2012-04-12 10 views
7

Estoy usando Django 1.3.1. Tengo dos bases de datos, algunas de mis modelos viven en una base de datos, otras en la otra. Ambas bases de datos son bases de datos contrib.gis.db.backends.postgis.Django TestCase no utiliza transacciones en la base de datos secundaria

Para mi sorpresa, Django's TestCase no está haciendo retrocesos en los cambios que realicé en la base de datos secundaria entre las 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 debe estar en la base de datos secundaria. La afirmación en la primera prueba tiene éxito, no pasa la segunda prueba:

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! 

Asumo que envuelve este Django en una transacción en la base de datos por defecto, 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 los ajustes para que todo salga a la misma base de datos, el problema desaparece)

Voy a añadir todo el código del router, en caso de que ayuda:

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

que debe incluir su enrutadores en la pregunta. Ahí es donde podría estar el problema. –

+0

Tengo un caso similar en el que la corrección 'connection._rollback()' para 'integrityerror' ya no funciona tan pronto como muevo el modelo a una base de datos separada. También modelos de Postgis, entonces tal vez hay algo mal en 'django.contrib.gis.db.models' – RickyA

+0

hey RemcoGerlich, ¿alguna vez encontraste una resolución? Estoy luchando con el mismo problema http://stackoverflow.com/questions/12205855/factory-boy-instance-within-testcase-causes-unique-contraint-violation –

Respuesta

Cuestiones relacionadas