with - zeppelin python




SQLAlchemy und mehrere Datenbanken (2)

Ich habe eine Auswahl von ähnlichen (aber nicht identischen) Datenbanken und möchte SQLAlchemy als eine Möglichkeit verwenden, um den Zugriff zu "standardisieren". Die Datenbanken können sehr unterschiedlich sein, z. B. ein eindeutiges Präfix für die Spaltennamen haben, oder sie können sich dramatisch unterscheiden und fehlende Spalten enthalten (oder für alte Datenbanken fehlen ganze Tabellen).

Was ich suche, ist nicht so sehr ein SQLAlchemy-Problem, sondern ein Python / organisatorisches Problem. Wie kann ich mehrere Datenbanken einrichten, die einfach in Projekten wiederverwendet werden können?

Ich habe über SQLAlchemy-Sitzungen gelesen, kann aber keine Möglichkeit sehen, diese zu verwenden, ohne jedes von ihnen in jedem Projekt instanziieren zu müssen.

Meine Frage ist: Wie kann ich ein Modul / Paket erstellen, das viele Datenbankmodell-Setups enthält, die in SQLAlchemy verwendet werden können und die einfach in ein anderes Python-Projekt importiert / verwendet werden können?

Ich mache mir nicht so viele Sorgen um die fehlenden Spalten / Tabellen. Ich kann dieses Problem später angehen, aber es ist etwas, das beachtet werden muss, da ich nicht das exakt gleiche Modell für jede Datenbank verwenden kann.

Alle Ressourcen, Hinweise oder Lektüre zu diesem Thema würde wirklich geschätzt werden. Vielen Dank im Voraus, und es tut mir leid, wenn das an anderer Stelle beantwortet wurde, Suchvorgänge zeigten nichts dazu.

EDIT : Ich habe das Original intakt gelassen und füge mehr Inhalt basierend auf Pauls Rat hinzu.

RE: SA ORM - Ja, ich plane die Verwendung des SQLAlchemy ORM. Aus naheliegenden Gründen kann ich keine echten Datenbanken anbieten. Nehmen wir jedoch an, dass diese drei fiktiven Datenbanken mit dem passenden Namen DB1, DB2 und DB3 (wir nehmen jeweils eine Tabelle an, mit nur wenigen Spalten würde die reale Welt wesentlich mehr von beiden haben).

Jede Datenbank hat eine Benutzertabelle mit jeweils einigen Spalten. Folgendes ist eine SQL-Notation für die Tabellen / Spalten:

DB1.user  --> DB1.user.id,      DB1.user.username,  DB1.user.email
DB2.user  --> DB2.user.id,      DB2.user.user_name, DB2.user.email
DB3._user --> DB3._user.userid, DB3._user.username, DB3.user.email_address

Momentan versuche ich, diese Datenbanken auf "modular" zu verteilen und einfach zusätzliche Datenbanken hinzuzufügen.

Ich habe einige Aspekte der Dateiorganisation berücksichtigt (angenommen, dass __init__.py an den erforderlichen Stellen vorhanden ist, aber der Kürze halber weggelassen wird), einschließlich:

Databases         |    Databases            |    Databases
    DB1.py        |        DB1              |        DB1
    DB2.py        |            models.py    |            models
    DB3.py        |        DB2              |                user.py
                  |            models.py    |                anothertable.py
                  |        DB2              |        ...
                  |            models.py    |        DB3
                  |                         |            models
                  |                         |                user.py
                  |                         |                anothertable.py

Ich würde gerne mit dem SA ORM darauf zugreifen können, und zwar mit so wenig Import / Deklarationen wie möglich, wenn es an der Zeit ist, diese Datenbanken in einer Python-Datei zu verwenden. Etwas ähnliches tun müssen:

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from Database import DB1, ..., DB[N]
db1_engine = create_engine('connect_string/db1')
db1_session = sessionmaker(bind=db1_engine)()
...
db3_engine = create_engine('connect_string/db3')
db3_session = sessionmaker(bind=db3_engine)()

wäre unglaublich umständlich, da ich mit weit mehr als nur drei Datenbanken zu tun habe. Viel lieber hätte ich das schon für mich erledigt (vielleicht in der __init__.py Datei?)

In der Lage sein, darauf zuzugreifen und es ähnlich zu verwenden:

import Databases

Databases.DB1.session.query('blahblah')

wäre unendlich besser.

EDIT2 : Ich weiß auch, wie man die Varianten in den Namenskonventionen der Datenbanken / Spalten beim Einrichten meiner Modelle umgehen kann . Das ist kein Problem, aber ich habe es erwähnt, so dass es bekannt war, dass ich nicht nur ein Modell für mehrere Datenbanken verwenden kann.

Ich hoffe, dass ich dadurch das Wasser nicht verschmutze oder dies zu verwirrend mache. Danke, dass Sie sich die Zeit genommen haben, es zu lesen!

EDIT3 : Ich habe es geschafft, etwas mehr Zeit damit zu verbringen. Ich habe das Projekt folgendermaßen eingerichtet:

Databases
    __init__.py
    databases.py
    settings.py
    DB1
        __init__.py
        models.py
    ...
    DB3
        __init__.py
        models.py

Momentan habe ich eine Reihe von Datenbanken, die in der Datei settings.py "installiert" sind. Jeder Eintrag ist wie INSTALLED_DATABASES = ('DB1', ..., 'DB3') . Wenn ich mehr Modelle fertig habe, werden sie in die Tupelliste aufgenommen. Dadurch kann ich Inhalte hinzufügen oder entfernen.

Ich habe die Engine und Sessios Setup in der Datei models.py, und haben Sie die init.py- Datei für jede Datenbank-Setup from models import * .

In der Datei datasets.py habe ich Folgendes

class Databases(object):
    def __init__(self):
        for database in INSTALLED_DATABASES:
            setattr(self, database, __import__(database))

Ich kann sie jetzt über:

from databases import Databases

db = Databases()

for qr in db.DB1.query(db.DB1.User):
    print qr.userid, qr.username

SQLAlchemy erlaubt mir, Spaltennamen bei der Definition der Modelle manuell anzugeben, was ein großer Bonus für die von mir gewünschte Standardisierung ist.

Ich habe noch eine Menge Arbeit vor mir. Ich möchte Objekte erstellen, die die Modellvalidierung erzwingen (dh, ein Feld vorhanden ist? Hat ein nicht vorhandenes Feld einen Standardwert? Usw.) und besser integrieren, wie dies mit meiner IDE funktioniert (das ist zur Zeit nicht der Fall) ). Aber ich bin auf dem richtigen Weg. Ich dachte mir, ich würde das für jeden auf den neuesten Stand bringen, der sich zufällig fragt, wie ich das gleiche machen könnte wie ich.

Entschuldigung, das ist so lang geworden!

Prost!


Deine Lösung sieht ziemlich gut aus. Hier ist was ich getan habe.

Ich habe ein Paket namens connectors, und darin ein Modul für jede db sowie eine Einstellungsdatei.

Jedes dieser Connector-Module erstellt seine Verbindungszeichenfolge und seine Engine zusammen mit der deklarativen Basis und den Klassen für die Tabellen.

Dann gibt es eine Methode loadSession, die die Sitzung zurückgibt (die ich hier aus einem Tutorial oder einem anderen Post hier, kann mich nicht genau erinnern) und eine andere, die ich die Engine zurückgibt, falls ich etwas damit machen will.

Also würde ich in einem anderen Modul des Programms so etwas machen

from connectors import x, y, z

x_ses = x.loadSession()
y_ses = y.loadSession()
z_ses = z.loadSession()

xq = x_ses.query(...)
yq = y_ses.query(...)

Wie bei den Anfragen zu meiner ersten Frage, habe ich meinen dritten Schnitt gemacht und es zu meiner Antwort gemacht. Da ich mir der richtigen Protokolle nicht sicher bin, habe ich die dritte Bearbeitung oben an Ort und Stelle gelassen. Wenn Sie bereits EDIT3 gelesen haben, dann haben Sie gelesen, was ich als Antwort habe.

Ich habe es geschafft, etwas mehr Zeit damit zu verbringen. Ich habe das Projekt folgendermaßen eingerichtet:

Databases
    __init__.py
    databases.py
    settings.py
    DB1
        __init__.py
        models.py
    ...
    DB3
        __init__.py
        models.py

Momentan habe ich eine Reihe von Datenbanken, die in der Datei settings.py "installiert" sind. Jeder Eintrag ist wie INSTALLED_DATABASES = ('DB1', ..., 'DB3') . Wenn ich mehr Modelle fertig habe, werden sie in die Tupelliste aufgenommen. Dadurch kann ich Inhalte hinzufügen oder entfernen.

Ich habe die Engine und Sessios Setup in der Datei models.py, und haben Sie die init.py- Datei für jede Datenbank-Setup from models import * .

In der Datei datasets.py habe ich Folgendes

class Databases(object):
    def __init__(self):
        for database in INSTALLED_DATABASES:
            setattr(self, database, __import__(database))

Ich kann sie jetzt über:

from databases import Databases

db = Databases()

for qr in db.DB1.query(db.DB1.User):
    print qr.userid, qr.username

SQLAlchemy erlaubt mir, Spaltennamen bei der Definition der Modelle manuell anzugeben, was ein großer Bonus für die von mir gewünschte Standardisierung ist.

Ich habe noch eine Menge Arbeit vor mir. Ich möchte Objekte erstellen, die die Modellvalidierung erzwingen (dh, ein Feld vorhanden ist? Hat ein nicht vorhandenes Feld einen Standardwert? Usw.) und besser integrieren, wie dies mit meiner IDE funktioniert (das ist zur Zeit nicht der Fall) ). Aber ich bin auf dem richtigen Weg. Ich dachte mir, ich würde das für jeden auf den neuesten Stand bringen, der sich zufällig fragt, wie ich das gleiche machen könnte wie ich.

Entschuldigung, das ist so lang geworden!

Prost!





sqlalchemy