was macht sessionmaker()

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.
MoonKid
User
Beiträge: 105
Registriert: Mittwoch 10. Dezember 2014, 16:24

BlackJack hat geschrieben:`sessionmaker()` hat halt den Vorteil eine `Session`-Fabrik zu erstellen die anders konfiguriert ist als der Standard und man kann dann überall dieses „callable” benutzen um `Session`-Exemplare zu erstellen.
Warum sollte ich mehrere Instanzen von Session benötigen?
(btw: Der Satz ist zweideutig interpretierbar, da Python ja keinen Unterschied zwischen Klassen und Objekten macht. Schwierig!)
Also ich meine Objekte der Klasse Session.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

MoonKid hat geschrieben:Warum sollte ich mehrere Instanzen von Session benötigen?
Weil man dann Sessions mit verschiedenen Engines und verschiedenen Einstellung erzeugen kann. Manchmal hat man ja mehr als eine Datenbank oder eine Session soll sich anders verhalten.
Das Leben ist wie ein Tennisball.
BlackJack

@MoonKid: Neben dem was EyDu geschrieben hat, ist da ja auch die Frage wie lange eine Session existiert. Es ist nicht unübliche eine Session pro in sich geschlossener Aufgabe zu erzeugen. Was das konkret bedeutet hängt von der Anwendung und vom Entwurf des Programmierers ab. Bei Webanwendungen ist die Lebenszeit einer Session in der Regel auf einen Anfrage/Antwort-Zyklus beschränkt. Da werden also nacheinander neue Session-Objekte erzeugt. Und da mehr als eine Anfrage gleichzeitig kommen kann, sind auch parallel existierende Session-Objekte ein ganz normaler Fall.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@MoonKid: Du hast seltsame Ansichten, was was "global" sein sollte. Jeder Import legt ein Deinem Namensraum Namen von fremden Modulen ab, das als Forderung zu haben, ist also nicht einhaltbar. Nur weil die Variable in einem Klassennamensraum steht, der keine wirkliche Klasse ist, ist sie dennoch global. Was ich damit sagen will, alles in ein MDatabase macht nichts besser, sondern nur umständlicher für Dich. Wenn Du kennzeichnen willst, dass etwas nicht zur öffentlichen API gehört, kann man es mit einem Unterstrich kennzeichnen. Auf das Base-Beispiel angewendet: Auf Modulebene ein

Code: Alles auswählen

_Base = declarative_base()
ist die einzig richtige Vorgehensweise. Alle DB-Klassen erben dann von _Base.
Eine Klasse die wiederum SQLAlchemy kapselt scheint mir unnötig, weil SQLAlchemy ja schon eine Kapselung der Datenbankschnittstellen ist. Aber vielleicht kannst Du mich ja noch vom Gegenteil überzeugen.
Sessions sind nicht Thread-Safe, dass man für jeden Thread eine eigene Session braucht. Ich habe zum Beispiel für jede Transaktion eine eigene Session.
MoonKid
User
Beiträge: 105
Registriert: Mittwoch 10. Dezember 2014, 16:24

Sirius3 hat geschrieben:@MoonKid: Du hast seltsame Ansichten, was was "global" sein sollte.
Sie sind eher strikt. Fremde Module kann ich ja nicht beeinflussen. Soweit ich es beeinflussen kann, wir es aber gekapselt. Und ja sqlalchemy kapselt bereits die Schnittstelle zur Datenabank. Aber ich möchte sqlalchemy als Biblitothek selbst auch kapseln. Wenn ich später sqlalchemy austauschen will, muss ich das nur in der einen Datenbankklasse tun. Der Rest des Codes bleibt unberührt.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

MoonKid hat geschrieben:ich möchte sqlalchemy als Biblitothek selbst auch kapseln. Wenn ich später sqlalchemy austauschen will, muss ich das nur in der einen Datenbankklasse tun. Der Rest des Codes bleibt unberührt.
YAGNI.
In specifications, Murphy's Law supersedes Ohm's.
MoonKid
User
Beiträge: 105
Registriert: Mittwoch 10. Dezember 2014, 16:24

YAGNI

Ja, das Konzept ist mir ein Begriff. Ich entwickle aber nicht unter einem Chef und für einen Kunden. Das bedeutet, ich kann mir ein gewisses Maß an Perfektionismus erlauben. ;)

Ich sehe kein großes Problem darin, die "Funktionalität" der Datenbank bzw. der Datenschicht in einer eigenen Klasse zu kapseln. Dadurch wird der Code nicht merklich komplexer und fehleranfälliger. Er wird dafür jedoch wartungsfreudiger, da die Schichten klarer getrennt sind.

Wo sollte ich den ein Session und Engine Objekt sonst hintun? In den "globalen" Namensraum oder "modul-global"? Nö, das Thema hatten wir schon!
BlackJack

@MoonKid: Also wenn ich das richtig verstanden habe beschwerst Du Dich das `sessionmaker()` eine überflüssige Indirektion ist deren Sinn du nicht siehst, verteidigst aber im gleichen Atemzug deine überflüssige Indirektion. ;-)

Das mit der Perfektion hast Du nicht richtig verstanden:
“A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away.”
-- Antoine de Saint-Exupéry
Irgendwas sinnfreies da reinzubasteln nur weil man's kann und weils nicht weiter stört ist kein Perfektionismus.

Was zum Henker willst Du denn da noch mehr trennen? SA ist doch selbst schon eine Schicht um von der Datenbank zu abstrahieren. Die Datenschicht besteht doch dann in der Regel aus ORM-Klassen.

Hatten wir das Thema mit `Session` so schon? Das Ergebnis von `sessionmaker()` ist eine Klasse. Genau wie das Ergebnis von `deklarative_base()`. Diese Klassenobjekte gehören auf Modulebene. Du musst einfach nur damit klar kommen das Klassen in Python a) Objekte sind und b) zur Laufzeit dynamisch erzeugt werden. Ob das nun durch die Ausführung einer ``class``-Anweisung oder durch einen Funktionsaufruf passiert ist egal.
Antworten