Un aperçu en une ligne:
Le comportement de execute()
est la même dans tous les cas, mais ils sont 3 méthodes différentes, dans Engine
, Connection
et les Session
classes.
Qu'est-ce que c'est exactement execute()
:
Pour comprendre le comportement de execute()
nous devons nous pencher sur la Executable
classe. Executable
est une superclasse pour tous les types d'objets «instruction», y compris select (), delete (), update (), insert (), text () - en termes simples, une Executable
est une construction d'expression SQL prise en charge dans SQLAlchemy.
Dans tous les cas, la execute()
méthode prend le texte SQL ou l'expression SQL construite, c'est-à-dire l'une des différentes constructions d'expression SQL prises en charge dans SQLAlchemy et renvoie les résultats de la requête (a ResultProxy
- Enveloppe un DB-API
objet curseur pour faciliter l'accès aux colonnes de ligne.)
Pour le clarifier davantage (uniquement à des fins de clarification conceptuelle, pas une approche recommandée) :
En plus de Engine.execute()
(exécution sans connexion), Connection.execute()
et Session.execute()
, il est également possible d'utiliser execute()
directement sur n'importe quelle Executable
construction. La Executable
classe a sa propre implémentation de execute()
- Selon la documentation officielle, une ligne de description de ce que execute()
fait est " Compiler et exécuter ceciExecutable
". Dans ce cas, nous devons lier explicitement la Executable
(construction d'expression SQL) avec un Connection
objet ou un Engine
objet (qui obtient implicitement un Connection
objet), de sorte que le execute()
saura où exécuter le SQL
.
L'exemple suivant le montre bien - Compte tenu d'un tableau comme ci-dessous:
from sqlalchemy import MetaData, Table, Column, Integer
meta = MetaData()
users_table = Table('users', meta,
Column('id', Integer, primary_key=True),
Column('name', String(50)))
Exécution explicite, c'est-à Connection.execute()
- dire en passant le texte SQL ou l'expression SQL construite à la execute()
méthode de Connection
:
engine = create_engine('sqlite:///file.db')
connection = engine.connect()
result = connection.execute(users_table.select())
for row in result:
# ....
connection.close()
Exécution explicite sans connexion, c'est-à Engine.execute()
- dire en passant le texte SQL ou l'expression SQL construite directement à la execute()
méthode du moteur:
engine = create_engine('sqlite:///file.db')
result = engine.execute(users_table.select())
for row in result:
# ....
result.close()
L'exécution implicite ie Executable.execute()
- est également sans connexion, et appelle la execute()
méthode du Executable
, c'est-à-dire qu'elle appelle la execute()
méthode directement sur la SQL
construction d'expression (une instance de Executable
) elle-même.
engine = create_engine('sqlite:///file.db')
meta.bind = engine
result = users_table.select().execute()
for row in result:
# ....
result.close()
Remarque: a indiqué l'exemple d'exécution implicite à des fins de clarification - cette méthode d'exécution n'est pas recommandée - comme indiqué dans la documentation :
«L'exécution implicite» est un modèle d'utilisation très ancien qui, dans la plupart des cas, est plus déroutant qu'utile, et son utilisation est déconseillée. Les deux modèles semblent encourager la surutilisation de «raccourcis» opportuns dans la conception des applications, ce qui entraîne des problèmes plus tard.
Vos questions:
Si je comprends bien, si quelqu'un utilise engine.execute, il crée une connexion, ouvre une session (Alchemy s'en soucie pour vous) et exécute la requête.
Vous avez raison pour la partie "si quelqu'un l'utilise engine.execute
crée connection
" mais pas pour "ouvre session
(Alchemy s'en soucie pour vous) et exécute la requête" - En utilisant Engine.execute()
et Connection.execute()
est (presque) la même chose, en formel, l' Connection
objet est créé implicitement , et dans un cas ultérieur, nous l'instancions explicitement. Ce qui se passe réellement dans ce cas est:
`Engine` object (instantiated via `create_engine()`) -> `Connection` object (instantiated via `engine_instance.connect()`) -> `connection.execute({*SQL expression*})`
Mais y a-t-il une différence globale entre ces trois façons d'accomplir une telle tâche?
Au niveau de la couche DB, c'est exactement la même chose, tous exécutent du SQL (expression de texte ou diverses constructions d'expression SQL). Du point de vue de l'application, il existe deux options:
- Exécution directe - Utilisation
Engine.execute()
ouConnection.execute()
- L' utilisation
sessions
- gère efficacement transaction comme simple unité de travail, avec facilité via session.add()
, session.rollback()
, session.commit()
, session.close()
. C'est le moyen d'interagir avec la base de données en cas d'ORM, c'est-à-dire de tables mappées. Fournit identity_map pour obtenir instantanément des objets déjà accédés ou nouvellement créés / ajoutés au cours d'une seule demande.
Session.execute()
utilise finalement la Connection.execute()
méthode d'exécution de l'instruction afin d'exécuter l'instruction SQL. L'utilisation d' Session
objet est le moyen recommandé par SQLAlchemy ORM pour une application d'interagir avec la base de données.
Un extrait de la documentation :
Il est important de noter que lors de l'utilisation de l'ORM SQLAlchemy, ces objets ne sont généralement pas accessibles; à la place, l'objet Session est utilisé comme interface avec la base de données. Cependant, pour les applications construites autour de l'utilisation directe d'instructions SQL textuelles et / ou de constructions d'expression SQL sans implication des services de gestion de niveau supérieur de l'ORM, le moteur et la connexion sont roi (et reine?) - continuez à lire.