sessionmaker()
ist eine Fabrik, die dazu dient, Konfigurationsoptionen zum Erstellen neuer Session
Objekte an nur einem Ort zu platzieren. Es ist insofern optional, als Sie genauso einfach anrufen können, Session(bind=engine, expire_on_commit=False)
wann immer Sie ein neues benötigen Session
, mit der Ausnahme, dass es ausführlich und überflüssig ist, und ich wollte die Verbreitung kleiner "Helfer" stoppen, die sich jeweils mit dem Problem dieser Redundanz in einem neuen befassten und verwirrender Weg.
Es sessionmaker()
ist also nur ein Werkzeug, mit dem Sie Session
Objekte erstellen können, wenn Sie sie benötigen.
Nächster Teil. Ich denke, die Frage ist, was ist der Unterschied zwischen dem Erstellen eines neuen Session()
an verschiedenen Punkten und dem einfachen Verwenden eines neuen . Die Antwort nicht sehr. Session
ist ein Container für alle Objekte, die Sie in ihn einfügen, und verfolgt dann auch eine offene Transaktion. In dem Moment, in dem Sie rollback()
oder aufrufen commit()
, ist die Transaktion beendet und der Session
hat keine Verbindung zur Datenbank, bis er aufgefordert wird, SQL erneut auszugeben. Die Links, die es zu Ihren zugeordneten Objekten enthält, sind schwache Verweise, vorausgesetzt, die Objekte sind frei von ausstehenden Änderungen. Selbst in dieser Hinsicht Session
wird das System wieder in einen brandneuen Zustand versetzt, wenn Ihre Anwendung alle Verweise auf zugeordnete Objekte verliert. Wenn Sie die Standardeinstellung beibehalten"expire_on_commit"
Einstellung, dann sind alle Objekte nach einem Commit abgelaufen. Wenn dies Session
fünf oder zwanzig Minuten lang anhält und sich bei der nächsten Verwendung allerlei Dinge in der Datenbank geändert haben, wird beim nächsten Zugriff auf diese Objekte der brandneue Status geladen, obwohl sie sich im Speicher befinden für zwanzig Minuten.
In Webanwendungen sagen wir normalerweise: Hey, warum machst du nicht Session
bei jeder Anfrage eine brandneue , anstatt immer wieder dieselbe zu verwenden? Diese Vorgehensweise stellt sicher, dass die neue Anforderung "sauber" beginnt. Wenn einige Objekte aus der vorherigen Anforderung noch nicht mit Müll gesammelt wurden und Sie sie möglicherweise deaktiviert haben "expire_on_commit"
, hängt möglicherweise noch ein Status aus der vorherigen Anforderung herum, und dieser Status ist möglicherweise sogar ziemlich alt. Wenn Sie darauf achten, eingeschaltet zu bleiben expire_on_commit
und definitiv anzurufen commit()
oder rollback()
auf Anfrage zu enden, ist das in Ordnung, aber wenn Sie mit einem brandneuen Produkt beginnen Session
, gibt es nicht einmal die Frage, ob Sie sauber anfangen. Also die Idee, jede Anfrage mit einer neuen zu beginnenSession
expire_on_commit
Dies ist wirklich nur der einfachste Weg, um sicherzustellen, dass Sie neu beginnen, und um die Verwendung so gut wie optional zu machen, da dieses Flag für eine Operation, commit()
die mitten in einer Reihe von Operationen aufgerufen wird, viel zusätzliches SQL verursachen kann . Ich bin mir nicht sicher, ob dies Ihre Frage beantwortet.
In der nächsten Runde erwähnen Sie das Einfädeln. Wenn Ihre App Multithreading ist, empfehlen wir, sicherzustellen, dass die Session
verwendete App lokal für ... etwas ist. scoped_session()
Standardmäßig ist es lokal für den aktuellen Thread. In einer Web-App ist die lokale Anforderung sogar noch besser. Flask-SQLAlchemy sendet tatsächlich eine benutzerdefinierte "Bereichsfunktion" an, scoped_session()
damit Sie eine Sitzung mit Anforderungsbereich erhalten. Die durchschnittliche Pyramid-Anwendung fügt die Sitzung in die "Anforderungs" -Registrierung ein. Wenn Sie solche Schemata verwenden, scheint die Idee "Neue Sitzung auf Anfrage erstellen" weiterhin die einfachste Möglichkeit zu sein, die Dinge gerade zu halten.