Warum db.Sitzung.remove() aufgerufen werden muss?
Bin ich nach einem tutorial, um zu erfahren Kolben web-Entwicklung, und hier ist der unit-Test-Datei:
import unittest
from flask import current_app
from app import create_app, db
class BasicsTestCase(unittest.TestCase):
def setUp(self):
self.app = create_app('testing')
self.app_context = self.app.app_context()
self.app_context.push()
db.create_all()
def tearDown(self):
db.session.remove()
db.drop_all()
self.app_context.pop()
def test_foo(self):
pass
Habe ich dann auch gefunden, diese Sätze in SQLAlchemy-Dokument:
Mithilfe der oben genannten Fluss, der Prozess der Integration der
Session
mit
die web-Anwendung hat genau zwei Anforderungen:
......
Sicherzustellen, dass
scoped_session.remove()
wird aufgerufen, wenn der web-Anfrage endet, in der Regel durch die Integration mit dem web-framework das event-system
Schaffung einer "auf Anfrage Ende" - Ereignis.
Meine Frage ist: Warum muss ich anrufen db.session.remove()
?
Ich denke, so lange db.session.commit()
wird nicht aufgerufen, wird die Datenbank nicht geändert werden. Auch, wenn ich diese Zeile auskommentieren, wird die Anwendung noch in der Lage sein, um übergeben Sie die unit-test.
Habe ich konsultiert, die Dokumente sowohl von Flask-SQLAlchemy und SQLAlchemy, aber die erstere nicht einmal erwähnt db.session.remove()
, während die letzteren ist zu Abstrakt für mich zu verstehen.
- Ja, aber ich denke, dass eine Sitzung automatisch entfernt, wenn eine Anfrage kommt zu einem Ende.
- das war im Grunde war ich versucht zu sagen, ist es der Kontext, der code in deiner Frage sehe ich keine Verwendung für Sie.
- Ich habe aktualisiert die Frage: Es ist nicht nur code, sondern auch das Dokument, das verwirrt mich.
- Ich vorstellen, die Freigabe der db-Verbindung wieder in den pool ist ganz wichtig und das ist es, was die docs sagen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
In SQLAlchemy, über die Aktion erwähnt wird, weil die Sitzungen in der web-Anwendung sollten Gültigkeitsbereich, was bedeutet, dass jeder request-handler erstellt und zerstört seine eigenen Sitzung.
Dies ist notwendig, da web-Server kann multi-threaded, so dass mehrere Anfragen könnte, serviert in der gleichen Zeit, indem Sie jeder mit einer anderen Datenbank-Sitzung.
Diesem Szenario ist wunderschön verarbeitet von Flask-SQLAlchemy, es schafft ein frisches oder neues Gültigkeitsbereich session für jede Anfrage. Wenn Sie weiter Graben, wirst du feststellen,hier, es installiert auch der Haken, auf den
app.teardown_appcontext
(für Fläschchen >=0.9),app.teardown_request
(für Fläschchen 0.7-0.8),app.after_request
(für Fläschchen <0,7) und hier ist es, wo es fordertdb.session.remove()
.Den testen Umgebung nicht vollständig replizieren die Umwelt eine echte Anforderung, da es nicht push/pop den Anwendungskontext. Aufgrund der, dass die session nie entfernt am Ende der Anfrage.
Als seitliche Anmerkung, beachten Sie, dass die Funktionen registriert mit
before_request
undafter_request
sind auch nicht aufgerufen, wenn Sie anrufenclient.get()
.Können Sie erzwingen, dass eine Anwendung Kontext automatisch push und pop mit einer kleinen änderung an Ihrem test anstatt manuell die push-in
setUp()
und pop intearDown()
:mit dieser änderung ist der test bestanden wird, ohne manuell schreiben
db.session.remove()
.In der Dokumentation für Kolben-Tests scheint falsch zu sein oder eher veraltet. Vielleicht die Dinge funktionieren, wie Sie beschreiben, an einem gewissen Punkt, aber das ist nicht genau für die aktuelle Flasche und Flask-SQLAlchemy-Versionen.
Ich hoffe, das hilft!
with app.app_context():
Ansatz!setUp()
und poping intearDown()
, und (ii)with app.app_context():
?after_request
undbefore_request
tun bekommen, währendclient.get()
. Aber, es stimmt, dass die Auslösungclient.get()
während innerhalb einerAppContext
wie Sie getan wird Ergebnis inRequestContext
schieben nicht eineAppContext
seiner eigenen (das ist übrigens, warum es keineAppContext
Abrüsten und keine Auslösung des eingetragenenteardown_appcontext
- Handler). Der doc erwähnt, dassapp.test_request_context()
löst keinebefore_request
undafter_request
.Ich nicht verstehen, warum
db.session.remove()
notwendig ist, bis ich inspizierte das gesamte Projekt:Dies ist, weil in
config.py
,SQLALCHEMY_COMMIT_ON_TEARDOWN
eingestellt istTrue
. Als Ergebnis änderungendb.session
wäre automatisch verpflichtet, wenndb.session
nicht zerstört.