2010-09-03 5 views
20

Dies ist hoffentlich eine einfache Frage.Mehrere Datenbankkonfiguration in Django 1.2

Ich habe Probleme mit der Dokumentation der neuen Mehrfachdatenbankfunktion in Django 1.2. In erster Linie finde ich kein Beispiel dafür, wie Sie tatsächlich die zweite Datenbank in einem Ihrer Modelle verwenden.

Wenn ich in meiner models.py eine neue Klasse definiere, wie gebe ich an, mit welcher Datenbank ich mich verbinden möchte?

Mein settings.py enthält etwas ähnliches -

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',     
    } 

} 

Edit: Ich wurde am Router wie ein Dummy in der Dokumentation zu lesen. Wenn jemand anderes damit zu kämpfen hat, lesen Sie es zwei- oder dreimal, bevor Sie aufgeben!

Antwort

25

Ja, es ist ein bisschen kompliziert.

Es gibt eine Reihe von Möglichkeiten, wie Sie es implementieren können. Grundsätzlich müssen Sie angeben, welche Modelle zu welcher Datenbank gehören.

Erste Option

Hier ist der Code, den ich verwende; ich hoffe es hilft.

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 

Die Art und Weise dies funktioniert, ist ich eine Datei mit dem Namen der Datenbank erstellen meine Modelle zu verwenden, das hält. In diesem Fall würden Sie eine separate models-ähnliche Datei namens asterisk.py erstellen, die sich im selben Ordner wie die Modelle für Ihre App befindet.

In Ihrer models.py Datei, Sie

from asterisk import * 

Dann fügen würden, wenn Sie tatsächlich einen Datensatz aus diesem Modell fordern, funktioniert es so etwas wie diese:

  1. records = MyModel.object.all()
  2. Modul für MyModel ist myapp.asterisk
  3. gibt es eine Verbindung namens "asterisk" also verwenden Sie es anstelle von "default"

Zweite Option

Wenn Sie wollen die Kontrolle per-Modell der Datenbank Wahl haben, wie etwas, das funktionieren würde:

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 

Dann für jedes Modell:

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

Beachten Sie, dass ich diese zweite Option nicht getestet habe.

+1

Sorry für die verzögerte Antwort, aber das war immens hilfreich! – HurnsMobile

+0

Hallo, ich habe Ihre zweite Option implementiert. Es funktioniert gut außer allow_syncdb. Ich werde eine Antwort unten mit einem funktionierenden allow_syncdb für zukünftige Sucher veröffentlichen. – Rich

+0

Danke dafür! Ich hatte eine Zeitlang versucht, das von den Django-Doktoren zu finden. –

3

Hilft die Dokumentation auf automatic database routing und manually selecting a database nicht?

+0

ich aber so weit etwas können fehlen, wie ich es keine Beispiele sind sagen kann, wie ein Modell mit etwas neben der Standard-Datenbank zu definieren. – HurnsMobile

+0

+1. Django hat eine gute Dokumentation und die Dokumente sind fast immer die erste Adresse. –

+1

Wie in der Frage erwähnt, habe ich Probleme, die Dokumentation zu verstehen ... – HurnsMobile

8

Ein Addendum zu Jordans Antwort oben.richtig Für die zweite Option arbeitet die allow_syncdb Methode wie folgt:

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

Interessant! Also setzen Sie connection_name im Modell? –

+0

Ja. Und es funktioniert ziemlich gut, außer für ManyToMany Bereiche, in denen ich eine angeben müssen ‚durch‘ -Modell sonst Django die ‚durch‘ Tabelle in der Standarddatenbank erzeugt. – Rich

+0

Wow! Das werde ich mir definitiv merken. Gute Arbeit Reich. – HurnsMobile

Verwandte Themen