Guten Abend,
in einer Datenbank-Anwendung, die später SQLite, PostgreSQL und evt.
weitere Enginges bedienen soll, habe ich folgende Situation:
Modell.py definiert mir Objekte, die auf einer SQL-DB operieren. Dieses
Modul möchte ich auch für andere DB-Anwendungen nutzen können. Daher
kennt Modell.py die tatsächliche DB nicht.
Modelle.py definiert anwendungsspezifisch Objekte, die die jeweilige
SQL-Tabellenstruktur abbilden. Grundlage dafür sind die (generischen)
Objekte aus Modell.py
Tools.py definiert weitere anwendungsspezifische Operationen auf der DB,
typischerweise SELECT Anwendungen für Auswertungen.
Main.py ist das Hauptprogramm. Das Hauptprogramm bekommt vom Benutzer
z.B. auch Benutzernamen und Passwort für den DB-Zugang.
Mein Problem: Wie bekommen Modell.py und Tools.py einen gültigen
DB-Konnektor? Möglichst sogar den selben?
Folgenden Versuch habe ich gemacht:
In Modell.py gibt es eine
Klasse DB_Konnektor mit einem Zustand DB_Konnektor.DB und einer Methode
DB_Konnektor.Init(Zugangsdaten); letztere erzeugt den DB_Konnektor und
speichert ihn in dem Klassenzustand DB_Konnektor.DB
Außerdem gibt es in Modell.py die
Funktion DB(), die einfach den Zustand DB_Konnektor.DB zurück gibt.
In Main.py, Modelle.py und Tools.py kann ich nun aus Modell.py den
DB_Konnektor und die Funktion DB() importieren. Und tatsächlich scheint
der DB_Konnektor nach Aufruf von DB_Konnektor.Init(Zugangsdaten)
sichtbar zu sein.
Den Code der Python-Files habe ich unten wiedergegeben.
Ist das ein gutes, "pythonisches" Vorgehen? Oder gibt es eine elegantere
Möglichkeit?
Unschön bleibt aus meiner Sicht, dass der DB-Konnektor nur über eine
Funktion zugänglich ist, also DB(). Schöner wäre DB, also eine "Zustand
des Moduls" - aber das gibt es wohl nicht? So sieht die Syntax später
z.B. so aus:
Cur = DB().cursor()
DB().commit()
Schöner wäre:
Cur = DB.Cursor()
DB.commit()
Wäre es naheliegend, die Klasse DB_Konnektor von den Konnektor-Klassen
der implementierten Schnittstellen erben zu lassen? Also etwa:
class DB_Konnektor(sqlite3.Connector, psycopg2.extensions.connection)
def __init__(Typ, ...):
if Typ == 'SQLite':
sqlite3.Connector.__init__(...)
elif Typ == 'PostgreSQL':
psycopg2.extensions.connection.__init__(...)
...
Vielen Dank für Hilfe oder Hinweise!
Gruß Ulrich
Hier mein vorläufiger Code:
====== Modell.py ======
class DB_Konnektor():
DB = "DB Prototyp (unbrauchbar)"
def Init(DB_Name):
DB_Konnektor.DB = DB_Name
def DB():
return DB_Konnektor.DB
class Modell():
def DB(self):
print('Aus Sicht von Modell.Modell ist DB: {}'.format(DB()))
return DB_Konnektor.DB
### Die Klasse Modell ist in Wirklichkeit sehr umfangreich.
### Sie greift auf den DB-Konnektor zurück.
###
### Hier folgen weitere Objekte, die auch auf den DB-Konnektor
### zurückgreifen.
====== Modelle.py ======
from Modell import *
### Hier folgen die Klassen, die Datenbank-Tabellen abbilden.
### Grundlage dafür sind die in Test_Modell
### definierten Objekte.
====== Tools.py ======
from Modelle import *
def Tools():
print('Aus Sicht von Tools ist DB: {}'.format(DB()))
### Hier folgen eine Reihe von Objekten, die auf den
### DB-Konnektor zurückgreifen.
=== Main.py ===
from Modell import DB
from Modelle import *
from Tools import *
M = Modell()
### Vor dem Aufruf von DB_Konnektor.Init() sieht es so aus:
print('Aus Sicht des Hauptprogramms vor Init ist DB: {}'.format(DB()))
print('Aus Sicht des Hauptprogramms vor Init ist M.DB: {}'.format(M.DB()))
Tools()
### Aufruf von DB_Konnektor.Init(Zugangsdaten):
DB_Konnektor.Init("DB brauchbar.")
### Nach dem Aufruf von DB_Konnektor.Init(Zugangsdaten)
### sieht es so aus:
print('Aus Sicht des Hauptprogramms nach Init ist DB: {}'.format(DB()))
print('Aus Sicht des Hauptprogramms nach Init ist M.DB: {}'.format(M.DB()))
Tools()
--
Ulrich Goebel
Hainallee 40, 44139 Dortmund