Enrutamiento de múltiples bases de datos de Django

He estado usando la selección manual de bases de datos para hacer frente a un proyecto que tiene dos bases de datos independientes. He definido mis bases de datos en la configuración.

Después de leer un poco más, parece que el enrutamiento de la base de datos es en realidad el camino a seguir. Sin embargo, después de leer los documentos y algunas publicaciones relevantes aquí, estoy más confundido que nunca.

En mi configuración tengo:

DATABASES = {
    'default': {
       .... 
    },
    'my_db2': {
       ....
    }
}

DATABASE_ROUTERS = ['myapp2.models.MyDB2Router',]

Sé que tengo que definir mi clase de enrutador (yo pensar in myapp2.models.py archivo) así:

class MyDB2Router(object):
"""A router to control all database operations on models in
the myapp2 application"""

def db_for_read(self, model, **hints):
    if model._meta.app_label == 'myapp2':
        return 'my_db2'
    return None

def db_for_write(self, model, **hints):
    if model._meta.app_label == 'myapp2':
        return 'my_db2'
    return None

def allow_relation(self, obj1, obj2, **hints):
    if obj1._meta.app_label == 'myapp2' or obj2._meta.app_label == 'myapp2':
        return True
    return None

def allow_syncdb(self, db, model):

    if db == 'my_db2':
        return model._meta.app_label == 'myapp2'
    elif model._meta.app_label == 'myapp2':
        return False
    return None

¿Y que? ¿Cada modelo requiere un meta.app_label ¿O es eso automático? Aparte de eso, sigo recibiendo un error:

django.core.exceptions.ImproperlyConfigured: Error al importar el enrutador de la base de datos JournalRouter: "no se puede importar la conexión del nombre

¿Alguien puede ayudarme a entender qué está pasando y qué está mal? Cualquier ayuda muy apreciada.

preguntado el 08 de noviembre de 11 a las 16:11

Bien, acabo de resolver mi propio problema. La clase de enrutador entra en un archivo separado llamado routers.py en / myapp2. No se requiere meta.app_label ya que supongo que se asigna automáticamente. Espero que esto ayude a alguien. -

Cree una nueva respuesta a su pregunta y acéptela luego. -

Solo necesitas usar el app_label opción si el modelo se define fuera del models.py, de lo contrario se asigna automáticamente. -

4 Respuestas

Bien, acabo de resolver mi propio problema. La clase de enrutador entra en un archivo separado llamado routers.py en / myapp2. En meta.app_label se requiere ya que supongo que se asigna automáticamente. Espero que esto ayude a alguien. También he documentado el proceso aquí.

respondido 09 nov., 11:20

Acepte su respuesta para que sea más fácil para otros entender que esta es una respuesta correcta. - arulmr

No me ayudó, así que hice algunas depuraciones. Quizás los resultados puedan ahorrarle algo de dolor a alguien. :) El problema en django 1.4 es una referencia circular que ocurre cuando django intenta importar la clase de enrutador personalizada.
Esto sucede en django.db.utils.ConnectionRouter. En mi caso, la aplicación __init__.py importó un módulotastypie.api para ser precisos) que a su vez (y a través de una larga cadena) importó django.db.models. Eso no es malo en sí mismo, pero models intenta importar connection desde django.db y eso pasa a tener una dependencia de ConnectionRouter. Que es exactamente donde comenzó nuestro viaje. De ahí el error.

Esto se describe como un error en django <1.6 aquí: https://code.djangoproject.com/ticket/20704 y hay un pequeño conjunto de cambios que se supone que lo arreglará en django 1.6:https://github.com/django/django/commit/6a6bb168be90594a18ab6d62c994889b7e745055

Sin embargo, mi solución fue simplemente moverme routers.py desde el directorio de la aplicación al directorio del proyecto. No hay dependencias desagradables allí.

Respondido 26 Jul 13, 22:07

Esto es lo que me solucionó (junto con el consejo de @Janosch): placas

Moví mi clase de enrutamiento a mi proyecto principal y esto solucionó el error "No se puede importar la conexión de nombre" para mí también. ¡Gracias! - Steve Mayne

Un error más a omitir, es importar los modelos en el enrutador, esto conducirá al mismo error, incluso si el enrutador está definido en un archivo diferente.

Respondido el 27 de enero de 13 a las 14:01

Gracias, ¡esto me ahorró mucho tiempo! - Gill Bates

¡Esto es muy importante! Gracias por la respuesta. - Thane Brimhall

E incluso algo tan simple como from app.models import some_fun causará este error (en django 1.5). - placas

Si tiene una aplicación que usa varias bases de datos, puede enrutar por aplicación y por tabla. Por ejemplo, si su aplicación es "consola" y solo desea que el modelo "PoolServers" provenga de un back-end diferente, lo pondría en sus routers.py

class PoolServerRouter(object): 
def db_for_read(self, model, **hints):
    "Point only reads to poolserver  model to 'hamburger'"
    if model._meta.app_label == 'console' and model._meta.db_table == 'PoolServers':
        return 'hamburger'
    return 'default'

Respondido el 21 de diciembre de 16 a las 00:12

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.