2010-09-03 15 views
20

Esperamos que esta sea una pregunta fácil.Configuración de múltiples bases de datos en Django 1.2

Estoy teniendo algunos problemas para entender la documentación para la nueva función de múltiples bases de datos en Django 1.2. En primer lugar, parece que no puedo encontrar un ejemplo de cómo UTILIZAS la segunda base de datos en uno de tus modelos.

Cuando defino una nueva clase en mi models.py ¿Cómo se especifica qué base de datos tengo la intención de conectar a?

Mi settings.py contiene algo similar a -

DATABASES = { 
    'default': { 
     'ENGINE': 'django.db.backends.mysql', 
     'NAME': 'modules', 
     'USER': 'xxx',      
     'PASSWORD': 'xxx',     
    }, 
    'asterisk': { 
     'ENGINE': 'django.db.backends.mysql', 
     'NAME': 'users',      
     'USER': 'xxxx',      
     'PASSWORD': 'xxxx',     
    } 

} 

Editar: Yo estaba leyendo la documentación en los routers como un maniquí. Si alguien más está luchando con esto, ¡asegúrese de leerlo 2 o 3 veces antes de darse por vencido!

Respuesta

25

Sí, es un poco complicado.

Hay un número de maneras en que podría ponerla en práctica. Básicamente, necesita alguna forma de indicar qué modelos están asociados con qué base de datos.

Primera opción

Aquí está el código que utilizo; Espero eso ayude.

from django.db import connections 

class DBRouter(object): 
    """A router to control all database operations on models in 
    the contrib.auth application""" 

    def db_for_read(self, model, **hints): 
     m = model.__module__.split('.') 
     try: 
      d = m[-1] 
      if d in connections: 
       return d 
     except IndexError: 
      pass 
     return None 

    def db_for_write(self, model, **hints): 
     m = model.__module__.split('.') 
     try: 
      d = m[-1] 
      if d in connections: 
       return d 
     except IndexError: 
      pass 
     return None 

    def allow_syncdb(self, db, model): 
     "Make sure syncdb doesn't run on anything but default" 
     if model._meta.app_label == 'myapp': 
      return False 
     elif db == 'default': 
      return True 
     return None 

La forma en que esto funciona es creando un archivo con el nombre de la base de datos para usar que contiene mis modelos. En su caso, crearía un archivo de estilo models separado llamado asterisk.py que estaba en la misma carpeta que los modelos para su aplicación.

En el archivo models.py, deberá añadir

from asterisk import * 

Luego, cuando en realidad se solicita un registro de ese modelo, funciona algo como esto:

módulo
  1. records = MyModel.object.all()
  2. para MyModel es myapp.asterisk
  3. hay una conexión llamada "asterisco" a fin de utilizar en lugar de "default"

segunda opción

Si desea tener un control por modelo de elección de base de datos, algo como esto funcionaría:

from django.db import connections 

class DBRouter(object): 
    """A router to control all database operations on models in 
    the contrib.auth application""" 

    def db_for_read(self, model, **hints): 
     if hasattr(model,'connection_name'): 
      return model.connection_name 
     return None 

    def db_for_write(self, model, **hints): 
     if hasattr(model,'connection_name'): 
      return model.connection_name 
     return None 

    def allow_syncdb(self, db, model): 
     if hasattr(model,'connection_name'): 
      return model.connection_name 
     return None 

Luego, para cada modelo:

class MyModel(models.Model): 
    connection_name="asterisk" 
    #etc... 

Tenga en cuenta que no he probado esta segunda opción.

+1

Disculpe la demora en la respuesta, ¡pero fue inmensamente útil! – HurnsMobile

+0

Hola, he implementado su segunda opción. Funciona muy bien, excepto para allow_syncdb. Voy a publicar una respuesta a continuación con un allow_syncdb de trabajo para los buscadores futuros. – Rich

+0

¡Gracias por esto! Estaba teniendo muchísimo tiempo tratando de asimilar esto de los documentos de django. –

3

¿La documentación sobre automatic database routing y manually selecting a database no ayuda?

+0

puedo estar perdiendo algo, pero por lo que yo puedo decir que no hay ejemplos de cómo definir un modelo con nada, además de la base de datos por defecto. – HurnsMobile

+0

+1. Django tiene una buena documentación y los documentos son casi siempre el primer lugar para buscar. –

+1

Como noté en la pregunta, tengo problemas para entender la documentación ... – HurnsMobile

8

Un apéndice a Jordans respuesta anterior.Para la segunda opción, el método allow_syncdb funciona correctamente de la siguiente manera:

def allow_syncdb(self, db, model): 
    if hasattr(model,'connection_name'): 
     return model.connection_name == db 
    return db == 'default' 
+0

¡Interesante! ¿Estás configurando connection_name en el modelo? –

+0

Sí. Y funciona bastante bien, excepto en muchos campos donde tengo que especificar un modelo 'a través'; de lo contrario, Django genera la tabla 'a través' en la base de datos predeterminada. – Rich

+0

¡Guau! Definitivamente voy a hacer una nota mental de esto. Buen trabajo Rich. – HurnsMobile

Cuestiones relacionadas