Wie macht man es richtig?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
burli
User
Beiträge: 1156
Registriert: Dienstag 9. März 2004, 18:22

Ich weiß ehrlich gesagt nicht, ob die Frage nicht vielleicht in Datenbanken oder Webframeworks, aber ich vermute, es ist ein Problem mit Python Grundlagen. Folgendes Problem: ich habe eine Flask Anwendung, in der ich eine Datenbank anspreche. Die Verzeichnisstruktur sieht in etwa so aus

Code: Alles auswählen

/myapp/
/myapp/runserver.py
/myapp/config.py

/myapp/app/
/myapp/app/__init__.py

/myapp/app/views/
/myapp/app/templates/
/myapp/app/static/

/myapp/app/model/
/myapp/app/model/__init__.py
/myapp/app/model/model1.py
/myapp/app/model/model2.py
Ich habe also kein Modul sondern ein Paket für die Model. In der model/__init__.py importiere ich die ganzen Model, ich erstelle die Datenbankverbindung mit metadata.bind und rufe setup_all() auf (Elixir). Das ganze sieht in etwa so aus.

Code: Alles auswählen

from elixir import metadata, setup_all, session
from model1 import Model1
from model2 import Model2

metadata.bind = "postgresql://user:pw@localhost/database"
session.configure(bind=metadata.bind)
metadata.bind.echo = True
setup_all()
Soweit funktioniert das ganze, ich weiß nur nicht, ob das guter Stil ist. Gibt es einen pythonischeren Weg?

Und meine zweite Frage: ich habe den String für die Datenbank momentan direkt in der __init__.py in /myall/app/model/ geschrieben. Jetzt würde ich aber gerne den Verbindungsstring in die config.py auslagern und app.config von Flask nutzen.

Code: Alles auswählen

app = Flask(__name__)
app.config.from_envvar('SETTINGS')
Die Envvar habe ich im System gesetzt und das Laden funktioniert soweit. Ich erstelle das app Objekt aber in /myapp/app/__init__.py. Wie bekomme ich das Objekt jetzt in das Model? Die Datenbankverbindung wird ja automatisch ausgeführt, sobald ich ein Model importiere.
Das schwierigste beim Programmieren ist, sinnvolle Variablen- und Funktionsnamen zu finden :lol:
lunar

Nun, ganz offensichtlich musst Du den Quelltext eben so umschreiben, dass die Verbindung zur Datenbank nicht implizit, sondern erst explizit nach dem Laden der Konfiguration aufgebaut wird. So schwer ist das doch nicht ...
burli
User
Beiträge: 1156
Registriert: Dienstag 9. März 2004, 18:22

lunar hat geschrieben:Nun, ganz offensichtlich musst Du den Quelltext eben so umschreiben, dass die Verbindung zur Datenbank nicht implizit, sondern erst explizit nach dem Laden der Konfiguration aufgebaut wird. So schwer ist das doch nicht ...
Anscheinend schon, weil ich gerade keinen Plan habe, was du meinst. Die Konfiguration wird geladen bevor das Model importiert wird
Das schwierigste beim Programmieren ist, sinnvolle Variablen- und Funktionsnamen zu finden :lol:
lunar

Momentan wird die Datenbankverbindung ganz offensichtlich implizit durch den Import des "model"-Pakets erstellt. Mal abgesehen davon, dass ein "import" per se aus diversen Gründen eigentlich keine Seiteneffekte haben sollte, hast Du ja bereits selbst festgestellt, dass man "import" keine Parameter mitgeben kann, um die beabsichtigten Seiteneffekte (e.g. den Aufbau der Datenbankverbindung) zu beeinflussen.

Die offensichtliche Lösung wäre jetzt, den betreffenden Quelltext von der Modulebene in eine Funktion zu verschieben, welche die Datenbankverbindung aufbaut und ein entsprechendes "Verbindungsobjekt" zurückgibt, und diese Funktion an geeigneter Stelle (e.g. nach dem Laden der Konfiguration) aufzurufen.
burli
User
Beiträge: 1156
Registriert: Dienstag 9. März 2004, 18:22

Ah, so wird ein Schuh draus, danke.

Aber wie ist das mit dem generellen Aufbau? Passt der so?
Das schwierigste beim Programmieren ist, sinnvolle Variablen- und Funktionsnamen zu finden :lol:
lunar

@burli: Über den „generellen Aufbau“ hast Du außer einer Liste der Dateien in Deinem Projekt nichts gesagt. Ich hoffe, Du erwartest von mir kein sinnvolles Urteil auf Basis dieser Informationen, denn hellsehen kann ich ehrlich nicht. :)
Antworten