Eine einzeilige Übersicht:
Das Verhalten execute()
ist das gleiche in allen Fällen, aber sie sind 3 verschiedene Methoden, in Engine
, Connection
und Session
Klassen.
Was genau ist execute()
:
Um das Verhalten von zu verstehen execute()
, müssen wir in die Executable
Klasse schauen . Executable
ist eine Oberklasse für alle "Anweisung" -Objekttypen, einschließlich select (), delete (), update (), insert (), text () - in einfachsten Worten Executable
ist es ein SQL-Ausdruckskonstrukt, das in SQLAlchemy unterstützt wird.
In allen Fällen verwendet die execute()
Methode den SQL-Text oder den konstruierten SQL-Ausdruck, dh eines der verschiedenen in SQLAlchemy unterstützten SQL-Ausdruckskonstrukte, und gibt Abfrageergebnisse zurück (a ResultProxy
- Umschließt ein DB-API
Cursorobjekt, um den Zugriff auf Zeilenspalten zu erleichtern.)
Zur weiteren Klärung (nur zur konzeptionellen Klärung, kein empfohlener Ansatz) :
Zusätzlich zu Engine.execute()
(verbindungslose Ausführung), Connection.execute()
und Session.execute()
, ist es auch möglich, das execute()
direkt auf jedem Executable
Konstrukt zu verwenden. Die Executable
Klasse hat eine eigene Implementierung von execute()
- Gemäß der offiziellen Dokumentation execute()
lautet eine einzeilige Beschreibung " Kompilieren und AusführenExecutable
". In diesem Fall müssen wir das Executable
(SQL-Ausdruckskonstrukt) explizit an ein Connection
Objekt oder ein Engine
Objekt (das implizit ein Connection
Objekt erhält ) binden , damit der execute()
weiß, wo das ausgeführt werden soll SQL
.
Das folgende Beispiel zeigt es gut - Gegeben eine Tabelle wie folgt:
from sqlalchemy import MetaData, Table, Column, Integer
meta = MetaData()
users_table = Table('users', meta,
Column('id', Integer, primary_key=True),
Column('name', String(50)))
Explizite Ausführung, dh Connection.execute()
Übergabe des SQL-Textes oder des erstellten SQL-Ausdrucks an die execute()
Methode Connection
:
engine = create_engine('sqlite:///file.db')
connection = engine.connect()
result = connection.execute(users_table.select())
for row in result:
# ....
connection.close()
Explizite verbindungslose Ausführung, dh Engine.execute()
Übergabe des SQL-Textes oder des erstellten SQL-Ausdrucks direkt an die execute()
Engine-Methode:
engine = create_engine('sqlite:///file.db')
result = engine.execute(users_table.select())
for row in result:
# ....
result.close()
Die implizite Ausführung, dh Executable.execute()
- ist ebenfalls verbindungslos und ruft die execute()
Methode von auf Executable
, dh sie ruft die execute()
Methode direkt für das SQL
Ausdruckskonstrukt (eine Instanz von Executable
) selbst auf.
engine = create_engine('sqlite:///file.db')
meta.bind = engine
result = users_table.select().execute()
for row in result:
# ....
result.close()
Hinweis: Das implizite Ausführungsbeispiel wurde zur Verdeutlichung angegeben - diese Art der Ausführung wird dringend empfohlen - gemäß den folgenden Dokumenten :
"Implizite Ausführung" ist ein sehr altes Verwendungsmuster, das in den meisten Fällen eher verwirrend als hilfreich ist und von dessen Verwendung abgeraten wird. Beide Muster scheinen die Überbeanspruchung zweckmäßiger „Abkürzungen“ im Anwendungsdesign zu fördern, die später zu Problemen führen.
Deine Fragen:
Soweit ich weiß, stellt jemand, der engine.execute verwendet, eine Verbindung her, öffnet eine Sitzung (Alchemy kümmert sich um Sie) und führt eine Abfrage aus.
Sie haben Recht für den Teil "Wenn jemand ihn verwendet engine.execute
, erstellt connection
", aber nicht für "Öffnen session
(Alchemy kümmert sich um Sie) und Ausführen der Abfrage" - Verwenden Engine.execute()
und Connection.execute()
ist (fast) dasselbe, formal wird das Connection
Objekt implizit erstellt und im späteren Fall instanziieren wir es explizit. Was in diesem Fall wirklich passiert, ist:
`Engine` object (instantiated via `create_engine()`) -> `Connection` object (instantiated via `engine_instance.connect()`) -> `connection.execute({*SQL expression*})`
Aber gibt es einen globalen Unterschied zwischen diesen drei Arten, eine solche Aufgabe auszuführen?
Auf der DB-Ebene ist es genau dasselbe, alle führen SQL aus (Textausdruck oder verschiedene SQL-Ausdruckskonstrukte). Aus Sicht der Anwendung gibt es zwei Möglichkeiten:
- Direkte Ausführung - Mit
Engine.execute()
oderConnection.execute()
- Mit
sessions
- effizient behandelt Transaktion als einzelne Einheit-of-Arbeit, mit Leichtigkeit über session.add()
, session.rollback()
, session.commit()
, session.close()
. Dies ist die Möglichkeit, bei ORM, dh zugeordneten Tabellen, mit der Datenbank zu interagieren. Bietet identity_map für den sofortigen Zugriff auf bereits aufgerufene oder neu erstellte / hinzugefügte Objekte während einer einzelnen Anforderung.
Session.execute()
Verwendet letztendlich die Connection.execute()
Anweisungsausführungsmethode, um die SQL-Anweisung auszuführen. Die Verwendung von Session
Objekten ist die von SQLAlchemy ORM empfohlene Methode für die Interaktion einer Anwendung mit der Datenbank.
Ein Auszug aus den Dokumenten :
Es ist wichtig zu beachten, dass bei Verwendung des SQLAlchemy ORM im Allgemeinen nicht auf diese Objekte zugegriffen wird. Stattdessen wird das Sitzungsobjekt als Schnittstelle zur Datenbank verwendet. Für Anwendungen, die auf der direkten Verwendung von textuellen SQL-Anweisungen und / oder SQL-Ausdruckskonstrukten ohne Beteiligung der übergeordneten Verwaltungsdienste des ORM basieren, sind Engine und Verbindung König (und Königin?) - lesen Sie weiter.