Programm Architektur

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
python_hulk
User
Beiträge: 5
Registriert: Dienstag 11. März 2014, 08:54

Hallo zusammen,

ich bin Python Anfänger und hätte gleich einmal eine Frage zur Programm/Datenbank Architektur.
Ich hoffe ihr könnt mir weiterhelfen.

Zuerst einmal die Problemstellung:

Ich bekomme Dateien, in denen sich Informationen zu Sendungen befinden (zb. Absender, Empfänger, Termin, Sendungspositionen, Packstücke, usw.)
Diese Informationen müssen dann in eine Datenbank gespeichert werden.
Zu beachten ist auch, dass die Dateien unterschiedlich aufgebaut sein können. Ich kenne aber den Aufbau der verschiedenen Datei-Arten.

Die Umsetztung hätte ich mir jetzt in etwa so vorgestellt:

Ich baue mir ein Interface (IDateiReader) mit der abstrakten Methode getSendungen.
Davon werden dann die verschiedenen unterschiedlichen DateiReader abgeleitet (zb. DateiReaderA, DateiReaderB,....)
Diese übernehmen dann das Auslesen der verschieden Dateien.

Zu meiner Frage:
Ist es sinnvoll, dass ich nun die komplette Datenbank in Form von Klassen abbilde (Klasse -> Tabelle),
sodass meine Methode getSendung, dann nur eine Sendungs-Klasse zurüchgeben muss, die wiederrum
verknüpfte Klassen besitzt (zb. Sendungsposition).

Für Ratschläge und Verbesserungsvorschläge wäre ich sehr dankbar.

Schöne Grüße
python_hulk
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@python_hulk: das was Du hier beschreibst, ist ein übliches Vorgehen unter dem Stichwort ORM. Für Python ist SQLAlchemy ein beliebtes Framework, um die Datenbankanbindung zu kapseln.
BlackJack

@python_hulk: Interfaces als Sprachkontrukt gibt es nicht, also den `IDateiReader` brauchst Du schon mal nicht. Die Frage ist ob es überhaupt Klassen geben muss als API, oder ob nicht Funktionen zum einlesen ausreichen. Wenn es Sinn macht, dass die dann eine oder mehrere Klassen für ihre Arbeit benötigen, dann kann man diese Klassen natürlich schreiben, aber für die API wäre es Unsinn wenn jedes Einlesen aus dem erstellen eines Reader-Exemplars besteht auf dem dann genau eine Methode aufgerufen wird. Also wenn es immer so aussieht: ``content = DateiReaderA('filename.txt').get_sendungen()``, dann sollte man wohl eher eine Funktion bereit stellen ``content = read_format_a('filename.txt')``.

Wenn Du Datenbanktabellen auf Klassen abbilden möchtest, und es sich um relationale DBs handelt, solltest Du mal einen Blick auf das `orm`-Modul von SQLAlchemy werfen.

Und bei der Schreibweise von `getSendungen()` auch mal in den Style Guide for Python Code. Vielleicht auch Python is not Java.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

BlackJack hat geschrieben:@python_hulk: Interfaces als Sprachkontrukt gibt es nicht, also den `IDateiReader` brauchst Du schon mal nicht.
Man könnte Abstract Base Classes als Interface ansehen.

Grundsätzlich stimme ich dir aber in deiner Einschätzung der Umsetzung zu.
BlackJack

@/me: Stimmt, an ABCs hatte ich nicht gedacht. Aber die sind für „inspection” gedacht und da ist die Frage wogegen man so einen Reader dynamisch im Quelltext abgrenzen will. Ich sehe da jetzt nicht wozu man offensichtlich `isinstance()` in dem beschriebenen Code verwenden muss.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Damit es nicht untergeht und noch mal explizit genannt wird: Du brauchst ein zentrales Domänenmodell der Daten, welche Du verarbeiten willst. BlackJack hatte das mit ``content = ...`` angedeutet, wobei ``content`` das zentrale Objekt des Domänenmodells ist (Eric Evans nennt das in seinem Buch "Domain Driven Design" Aggregate Root).

Dies kann man mit Klassen und / oder mit den eingebauten Datentypen von Python realisieren (Listen, Dictionaries usw.). Klassen sind dafür also auch nicht unbedingt notwendig.

Mal Schematisch dargestellt:

Code: Alles auswählen

Verschiedene Dateien / Quellen → Objekt Repräsentation → Datenbank / GUI / was auch immer
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
python_hulk
User
Beiträge: 5
Registriert: Dienstag 11. März 2014, 08:54

Vielen Dank an alle für die schnellen Antworten.
Ihr habt mir sehr weitergeholfen, ich werde mir das Ganze mal anschauen.
Antworten