Prinzipfrage: Globale db-Methoden Klasse sinnvoll???

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

In PyLucid hab ich z.Z. eine Klasse mit (fast) allen vorgefertigten DB-Abfragen, quasi eine Sammlung: http://pylucid.python-hosting.com/file/ ... tem/SQL.py

Ich könnte natürlich alle Abfragen kreuz und quer in den einzelen Bereichen verteilen... Aber das macht IMHO nur dann Sinn, wenn wirklich eine Abfrage nur einmal vorkommt. Für Abfragen die allerdings mehrmals auftauchen ist dieser zentrale Ansatz besser...

Nur ist diese Klasse immer größer und größer geworden... Mittlerweile gibt es evtl. ein paar Methoden die niergendwo gebraucht werden. Es ist also unübersichtlich geworden :(

Ich frage mich gerade wie ich das besser Strukturieren kann.

Es gibt einmal recht einfache Sachen wie:

Code: Alles auswählen

    def side_name_by_id( self, page_id ):
        "Liefert den Page-Name anhand der >page_id< zurück"
        return self.select(
                select_items    = ["name"],
                from_table      = "pages",
                where           = ("id",page_id)
            )[0]["name"]
Aber mittlerweile gibt es auch größere Methoden, die eigentlich nicht mehr nur die Aufgabe haben eine Bestimmte Information aus der DB zu holen, sondern die Methode verarbeitet das ganze dann auch direkt. Ein Beispiel wäre print_internal_page() oder print_internal_TAL_page()

Wie macht ihr das?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Leg dir lieber einen globalen datenbank connection pool an und hau dir deine methoden auf das Connection object, das eben dieser zurückgibt.
TUFKAB – the user formerly known as blackbird
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Also im Grunde hab ich das jetzt schon so, denn mit self.request.db kommt man an alles dran:

Code: Alles auswählen

self.request.db.side_name_by_id("blabla")

oder

self.request.db.select(
                select_items    = ["name"],
                from_table      = "pages",
                where           = ("id",page_id)
            )[0]["name"]

oder

self.request.db.cursor...
vielleicht sollte ich nur hingehen und die Sachen etwas Gruppieren...

Das heißt ich spalte die riesen Klasse in mehrere kleinere (Thematisch) auf und erbe immer von der vorherrigen... Dann ändert sich eigentlich nix, ist nur aufgeräumter...

Ist das eine gute Idee???

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
tabellar
User
Beiträge: 186
Registriert: Mittwoch 4. September 2002, 15:28

Vielleicht hilft Dir bei der DB Geschichte das Denken in "Zuständigkeiten".
Ich persönlich habe immer irgendwelche "Handler" oder "Manager" für das
Ausführen von Aufgaben.

Bei DB Anwendungen verwende ich immer "drei Zuständige":

1. Connection Manager (stellt ein DB Connection Objekt zur Verfügung)
2. Objekt Manager (liefert Objektpools für DB Objektmanipulation, insert, edit, delete ...)
3. Query Manager (liefert reine Select Statements für Listendarstellung etc.)

Im PyPerCom Projekt sieht man das ganze im Zusammenhang mit ORM...

Tabellar
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

tabellar hat geschrieben:1. Connection Manager (stellt ein DB Connection Objekt zur Verfügung)
2. Objekt Manager (liefert Objektpools für DB Objektmanipulation, insert, edit, delete ...)
3. Query Manager (liefert reine Select Statements für Listendarstellung etc.)
Ich hatte bisher nur zwei Bereiche... Einmal ein Connection-Manager und einmal der ganze Rest, was mit DB zu tun hat...

Eine Unterscheidung zwischen passiven Teilen (nur SELECT Abfragen) und aktiven Teilen (INSERT, UPDATE ect.), ist eine Überlegung wert...

Ist das allgemeiner Standard???

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
tabellar
User
Beiträge: 186
Registriert: Mittwoch 4. September 2002, 15:28

jens hat geschrieben:Ich hatte bisher nur zwei Bereiche... Einmal ein Connection-Manager und einmal der ganze Rest, was mit DB zu tun hat... Eine Unterscheidung zwischen passiven Teilen (nur SELECT Abfragen) und aktiven Teilen (INSERT, UPDATE ect.), ist eine Überlegung wert...
Ergänzung: Query- und Objektmanager greifen über das DB-Connection
Objekt vom Connection Manager zu. Die reine Anwendungsschicht nutzt
dann also ausschliesslich die Schnittstellen vom Objekt- und QueryMgr.
SQL Statements gibt es also nur dort...
jens hat geschrieben:Ist das allgemeiner Standard???
Hintergrund ist hier die Persistence Komponente von OPENQUASAR - Qualitäts-Software-Architektur.
Zentrale Themen sind dort das Denken in Schnittstellen und Komponenten. Ich bin durch ein Buch
auf das Thema aufmerksam geworden. In dem Buch ist das ganze auch besser dargestellt wie auf
den Web Seiten. QUASAR Persistence ist in Java implementiert. Im Prinzip habe ich das ganze dann mit Python realisiert.

Tabellar
N317V
User
Beiträge: 504
Registriert: Freitag 8. April 2005, 13:23
Wohnort: München

jens hat geschrieben:Aber mittlerweile gibt es auch größere Methoden, die eigentlich nicht mehr nur die Aufgabe haben eine Bestimmte Information aus der DB zu holen, sondern die Methode verarbeitet das ganze dann auch direkt. Ein Beispiel wäre print_internal_page() oder print_internal_TAL_page()

Wie macht ihr das?
Kurz: Ich würde das auf jeden Fall trennen.
Es gibt für alles eine rationale Erklärung.
Außerdem gibt es eine irrationale.

Wie man Fragen richtig stellt
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

N317V hat geschrieben:Kurz: Ich würde das auf jeden Fall trennen.
Das hatte ich auch vor...

Aber woran denkt ihr, beim trennen???

Ich hab z.Z. dieses eine DB-Objekt. Daran hängen direkt die ganzen Methoden um alles zu machen: db.cursor, db.select, db.insert und alle "vorgefertigen" Methoden.
Eigentlich wollte ich das so beibehalten, also keine Trennung des Objektes, sondern nur die Mega-Klasse mit den ganze "vorgefertigen" Methoden aufteilen. Allerdings wird am Ende doch wieder alles zusammen gebaut, weil die Klasse von der anderen erbt.
Somit bleibt das DB-Objekt so wie es ist, aber aufgeräumt hab ich dann ein wenig...

Was haltet ihr davon? Oder würde man das anders machen? Vielleicht drei db-Objekte? Eins für Low-Level zugang, eins für "nur Abfrage"-Methoden und eins für "verarbeitenden" Methoden??

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

So, ich hab jetzt mal angefangen aufzuräumen: http://pylucid.python-hosting.com/brows ... system/db/

Dabei ist das so:
  • database.py - Stellt die DB Verbindung her, bietet Dict-Cursor und Conn.Objekt
    SQL_wrapper.py - Mein Wrapper für die SQL-Befehle, erbt von database.py
    SQL_passive_statements.py - Alle "nur select" Befehle, erbt von SQL_wrapper.py
    SQL_active_statements.py - Alle SQL Sachen die Daten verändern, erbt von SQL_passive_statements.py
Nach außen hin bleibt alles beim alten, d.h. meine Module/Plugins können mit der DB so umgehen wie bisher auch.
Worüber ich mir noch Gedanken machen muß ist ein Connection-Pool, aber darum kümmer ich mich erst später...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten