Una panoramica di una riga:
Il comportamento di execute()
è uguale in tutti i casi, ma sono 3 metodi differenti, in Engine
, Connection
e Session
classi.
Che cosa è esattamente execute()
:
Per capire il comportamento di execute()
dobbiamo guardare in Executable
classe. Executable
è una superclasse per tutti i tipi di oggetti "istruzione", inclusi select (), delete (), update (), insert (), text () - in parole semplici possibili, Executable
è un costrutto di espressione SQL supportato in SQLAlchemy.
In tutti i casi il execute()
metodo accetta il testo SQL o l'espressione SQL costruita, ovvero una qualsiasi varietà di costrutti di espressioni SQL supportati in SQLAlchemy e restituisce risultati di query (a ResultProxy
- Avvolge un DB-API
oggetto cursore per fornire un accesso più facile alle colonne di riga.)
Per chiarire ulteriormente (solo per chiarimenti concettuali, non un approccio raccomandato) :
Oltre a Engine.execute()
(esecuzione senza connessione), Connection.execute()
e Session.execute()
, è anche possibile usare il execute()
direttamente su qualsiasi Executable
costrutto. La Executable
classe ha la propria implementazione di execute()
- Secondo la documentazione ufficiale, una riga di descrizione di ciò che execute()
fa è " Compila ed esegui questoExecutable
". In questo caso dobbiamo associare esplicitamente il Executable
(costrutto dell'espressione SQL) con un Connection
oggetto o un Engine
oggetto (che ottiene implicitamente un Connection
oggetto), quindi execute()
sapremo dove eseguire il SQL
.
L'esempio seguente lo dimostra bene - Data una tabella come di seguito:
from sqlalchemy import MetaData, Table, Column, Integer
meta = MetaData()
users_table = Table('users', meta,
Column('id', Integer, primary_key=True),
Column('name', String(50)))
Esecuzione esplicita, vale a dire Connection.execute()
- passaggio del testo SQL o dell'espressione SQL costruita al execute()
metodo di Connection
:
engine = create_engine('sqlite:///file.db')
connection = engine.connect()
result = connection.execute(users_table.select())
for row in result:
# ....
connection.close()
Esecuzione esplicita senza connessione ovvero Engine.execute()
- passaggio del testo SQL o dell'espressione SQL costruita direttamente al execute()
metodo di Engine:
engine = create_engine('sqlite:///file.db')
result = engine.execute(users_table.select())
for row in result:
# ....
result.close()
L'esecuzione implicita, cioè Executable.execute()
- è anche senza connessione e chiama ilexecute()
metodo del Executable
, cioè chiama il execute()
metodo direttamente sul SQL
costrutto dell'espressione (un'istanza di Executable
) stessa.
engine = create_engine('sqlite:///file.db')
meta.bind = engine
result = users_table.select().execute()
for row in result:
# ....
result.close()
Nota: indicato l'esempio di esecuzione implicita a scopo di chiarimento - questo metodo di esecuzione è altamente sconsigliato - come da documenti :
"Esecuzione implicita" è un modello di utilizzo molto vecchio che nella maggior parte dei casi è più confuso di quanto sia utile e il suo utilizzo è scoraggiato. Entrambi i modelli sembrano incoraggiare l'uso eccessivo di "scorciatoie" opportune nella progettazione dell'applicazione che portano a problemi in seguito.
Le tue domande:
Come capisco se qualcuno usa engine.execute, crea una connessione, apre una sessione (Alchemy si preoccupa per te) ed esegue la query.
Hai ragione per la parte "se qualcuno lo usa engine.execute
crea connection
" ma non per "si apre session
(Alchemy si prende cura di te per te) ed esegue la query" - Usare Engine.execute()
ed Connection.execute()
è (quasi) la stessa cosa, in formale, l' Connection
oggetto viene creato implicitamente e in un secondo momento lo istanziamo esplicitamente. Quello che succede davvero in questo caso è:
`Engine` object (instantiated via `create_engine()`) -> `Connection` object (instantiated via `engine_instance.connect()`) -> `connection.execute({*SQL expression*})`
Ma c'è una differenza globale tra questi tre modi di svolgere tale compito?
A livello di DB è esattamente la stessa cosa, tutti eseguono SQL (espressione di testo o vari costrutti di espressioni SQL). Dal punto di vista dell'applicazione ci sono due opzioni:
- Esecuzione diretta: utilizzando
Engine.execute()
oConnection.execute()
- Usando
sessions
- gestisce in modo efficace operazione come singola unità-di-lavoro, con facilità via session.add()
, session.rollback()
, session.commit()
, session.close()
. È il modo di interagire con il DB in caso di ORM, ovvero tabelle mappate. Fornisce identity_map per ottenere immediatamente l'accesso o gli oggetti appena creati / aggiunti durante una singola richiesta.
Session.execute()
utilizza infine il Connection.execute()
metodo di esecuzione dell'istruzione per eseguire l'istruzione SQL. L'uso Session
dell'oggetto è il modo consigliato da SQLAlchemy ORM per consentire a un'applicazione di interagire con il database.
Un estratto dai documenti :
È importante notare che quando si utilizza SQLAlchemy ORM, questi oggetti non sono generalmente accessibili; invece, l'oggetto Session viene utilizzato come interfaccia per il database. Tuttavia, per le applicazioni basate sull'utilizzo diretto di istruzioni testuali SQL e / o costrutti di espressioni SQL senza il coinvolgimento dei servizi di gestione di livello superiore dell'ORM, Engine e Connection sono re (e regina?) - continua a leggere.