Wie benutzt man eine andere Datenbank pro "Anwendungsinstanz" in Django?

8

Das Szenario

Wir haben zwei Anwendungen.

TheApp

TheApp ist eine unglaubliche App, die Kunden lieben. Jeder Kunde bekommt seine eigenen Instanz der Anwendung, dh jeder Kunde verwendet eine andere Datenbank (Name, Benutzer, Passwort). Die Datenbankverbindung sollte über die Domäne entschieden werden, aus der der Anfrage kommt herein.

%Vor%

Administrationsanwendung

Sollte TheApp-Instanzen für die Kunden erstellen / löschen können. Daher muss die neue Datenbank eingerichtet und die Konfiguration an irgendwo geschrieben werden. Der Weg, der entscheidet Welche DB für die eingehende Anfrage verwendet wird, sollte gut funktionieren und leicht zu verwalten sein.

Die Frage

Welcher ist der beste Weg zu entscheiden, welche Datenbankverbindung für eine Instanz verwendet werden soll? Was macht es? das beste? Was skaliert am besten?

Antworten, die ich mit ™

erstellt habe

Ich lese Zeug und das sind die Wege, auf die ich gekommen bin:

(wsgi-Dämon + settings.py) pro Instanz

Jeder Kunde erhält seine eigenen settings.py mit den Datenbank-Zugangsdaten. Einstellungen kann einige allgemeine Dinge aus einer freigegebenen Einstellungsdatei erben.

Für jede neue Einstellungsdatei muss eine neue wsgi-Instanz der Anwendung gestartet werden. Dies kann sich negativ auf viele Kunden auswirken? Erstellen Sie auch die Apache-Vhost-Dateien ist hässlich.

Verwendung von 'using' & amp; ein settings.py

Ich könnte es machen wie

%Vor%

und setzen THE_CURRENT_DB irgendwo (Middleware Thingy?) pro Anfrage. Aber es scheint hässlich zu sein, dies zu tun überall. Auch die settings.py/app muss jedes Mal neu geschrieben werden, wenn ein Kunde seine bekommt Instanz.

Ein settings.py + Anwendungs-Router

Ich habe noch nicht nachgesehen, ob ich im Router auf Informationen über die Anfrage zugreifen kann, aber wenn ja, könnte ich vielleicht entscheiden, welche der dbs in settings.py verwendet werden soll. So'ne Art wie Ссылка , aber nicht nach Modell aber pro Anfrage.

Einstellungen in einer Middleware ändern

Ich hatte gerade die Idee, dass vielleicht die dB-Einstellung in einer Middleware geändert werden könnte. Noch nicht Ein Blick, wie Middleware in Django funktioniert und was dort möglich ist.

Etwas unklarer anderer Weg

Da ich mit Django ziemlich neu bin, habe ich vielleicht einige Punkte verpasst oder einige von ihnen sind einfach total albern und schlecht. Was würdest du tun?

Warum nicht alles in einer Datenbank?

Nun. Weil ich denke, Trennung von Sachen ist gut. Und wenn schlimme Dinge passieren, sind nicht alle plötzlich betroffen.

    
toabi 01.11.2011, 18:13
quelle

2 Antworten

2

Dies ist leicht mit Middleware und Postgres Namespaces möglich. Hier ist ein schnelles und schmutziges Beispiel mit absolut keiner Fehlerbehandlung:

%Vor%

Wenn diese Middleware aktiviert ist, kann jeder Kunde vollständig getrennte Daten haben, und es ist keine Mopery erforderlich, damit es funktioniert. Es gibt jedoch ein paar Dinge zu wissen:

  1. Ein Problem besteht in der Entwicklung. Normalerweise füge ich eine if-Anweisung hinzu, um die obige Prozedur zu ignorieren, wenn settings.DEBUG True ist, aber du könntest auch virtuelle Hosts einrichten und deine hosts-Datei bearbeiten, um dies in der Entwicklung zu testen.
  2. Eine weitere Überlegung ist, dass Sie für jede Instanz einen separaten virtuellen Host ausführen müssen. Andernfalls können Probleme auftreten, bei denen sich Instanzdaten überschneiden können. Ich nehme an, das ist eine Art Threading-Problem, aber jemand schlauer als ich kann das wahrscheinlich ausführlicher erklären.
  3. Schließlich müssen Sie darüber nachdenken, wie Sie mit neuen Installationen und Schema-Updates umgehen. Django wird alles in das öffentliche Schema einfügen. Sie müssen lernen, wie Sie dieses Schema kopieren, um ein neues zu erstellen, und sich auch daran gewöhnen, Datenbankaktualisierungen zu scripten.
bogeymin 22.03.2012 20:32
quelle
1

Das ist eines dieser Szenarien, die die Schwäche des django Konfigurationsmoduls (Einstellungen) zeigen. Es gibt keinen "django-unterstützten" Weg, dies zu tun.

Ich denke, Sie könnten sich für eine Option entscheiden, die nur minimale Auswirkungen auf die Codepflege und Portabilität hat. Also schlage ich vor:

  • Verwenden Sie eine Middleware, um die Benutzerkonfiguration in einigen Datenstrukturen (django unterstützt) zu halten
  • Einstellungen vornehmen. DATABASE eine abrufbare Benutzerkonfiguration von oben holen (django hack)
  • Verwenden Sie die django-Funktion für mehrere Datenbanken, um auf Modelle zuzugreifen (django-Unterstützung)
Carlo Pires 01.11.2011 23:42
quelle