Una descripción general de una línea:
El comportamiento de execute()
es igual en todos los casos, pero son 3 métodos diferentes, en Engine
, Connection
y Session
clases.
Qué es exactamente execute()
:
Para comprender el comportamiento de, execute()
debemos mirar dentro de la Executable
clase. Executable
es una superclase para todos los tipos de objetos "enunciados", incluidos select (), delete (), update (), insert (), text (); en palabras más simples posibles, Executable
es una construcción de expresión SQL compatible con SQLAlchemy.
En todos los casos, el execute()
método toma el texto SQL o la expresión SQL construida, es decir, cualquiera de la variedad de construcciones de expresiones SQL compatibles con SQLAlchemy y devuelve los resultados de la consulta (a ResultProxy
- Envuelve un DB-API
objeto cursor para proporcionar un acceso más fácil a las columnas de fila).
Para aclararlo más (solo para aclaración conceptual, no es un enfoque recomendado) :
Además de Engine.execute()
(ejecución sin conexión), Connection.execute()
y Session.execute()
, también es posible usar execute()
directamente en cualquier Executable
construcción. La Executable
clase tiene su propia implementación de execute()
: Según la documentación oficial, una descripción de una línea sobre lo que execute()
hace es " Compilar y ejecutar estoExecutable
". En este caso, necesitamos vincular explícitamente la Executable
(construcción de expresión SQL) con un Connection
objeto o, Engine
objeto (que implícitamente obtiene un Connection
objeto), para execute()
que sepan dónde ejecutar el SQL
.
El siguiente ejemplo lo demuestra bien: dada una tabla como la siguiente:
from sqlalchemy import MetaData, Table, Column, Integer
meta = MetaData()
users_table = Table('users', meta,
Column('id', Integer, primary_key=True),
Column('name', String(50)))
Ejecución explícita, es decir Connection.execute()
, pasar el texto SQL o la expresión SQL construida al execute()
método de Connection
:
engine = create_engine('sqlite:///file.db')
connection = engine.connect()
result = connection.execute(users_table.select())
for row in result:
# ....
connection.close()
Ejecución explícita sin conexión, es decir Engine.execute()
, pasar el texto SQL o la expresión SQL construida directamente al execute()
método de Engine:
engine = create_engine('sqlite:///file.db')
result = engine.execute(users_table.select())
for row in result:
# ....
result.close()
La ejecución implícita, es decir Executable.execute()
, también no tiene conexión y llama al execute()
método de Executable
, es decir, llama al execute()
método directamente en el SQL
constructo de expresión (una instancia de Executable
) en sí mismo.
engine = create_engine('sqlite:///file.db')
meta.bind = engine
result = users_table.select().execute()
for row in result:
# ....
result.close()
Nota: Expresé el ejemplo de ejecución implícita con el propósito de aclarar, esta forma de ejecución no es muy recomendable, según los documentos :
La “ejecución implícita” es un patrón de uso muy antiguo que en la mayoría de los casos es más confuso que útil y se desaconseja su uso. Ambos patrones parecen alentar el uso excesivo de "atajos" convenientes en el diseño de la aplicación que conducen a problemas más adelante.
Tus preguntas:
Según tengo entendido, si alguien usa engine.execute, crea conexión, abre sesión (Alchemy se preocupa por usted) y ejecuta la consulta.
Tienes razón para la parte "si alguien lo usa engine.execute
crea connection
" pero no para "abre session
(Alchemy se preocupa por ti) y ejecuta la consulta" - Usando Engine.execute()
y Connection.execute()
es (casi) una misma cosa, formalmente, el Connection
objeto se crea implícitamente , y en un caso posterior lo instanciamos explícitamente. Lo que realmente sucede en este caso es:
`Engine` object (instantiated via `create_engine()`) -> `Connection` object (instantiated via `engine_instance.connect()`) -> `connection.execute({*SQL expression*})`
¿Pero hay una diferencia global entre estas tres formas de realizar tal tarea?
En la capa DB es exactamente lo mismo, todos ellos están ejecutando SQL (expresiones de texto o varias construcciones de expresiones SQL). Desde el punto de vista de la aplicación, hay dos opciones:
- Ejecución directa: utilizando
Engine.execute()
oConnection.execute()
- Utilizando
sessions
- gestiona de manera eficaz transacción como una sola unidad de trabajo, con facilidad a través de session.add()
, session.rollback()
, session.commit()
, session.close()
. Es la forma de interactuar con la base de datos en el caso de ORM, es decir, tablas mapeadas. Proporciona identity_map para obtener instantáneamente objetos ya accedidos o recién creados / agregados durante una sola solicitud.
Session.execute()
en última instancia, utiliza el Connection.execute()
método de ejecución de sentencias para ejecutar la sentencia SQL El uso de Session
objetos es la forma recomendada de SQLAlchemy ORM para que una aplicación interactúe con la base de datos.
Un extracto de los documentos :
Es importante tener en cuenta que cuando se usa el SQLAlchemy ORM, generalmente no se accede a estos objetos; en cambio, el objeto Session se usa como interfaz para la base de datos. Sin embargo, para las aplicaciones que se basan en el uso directo de sentencias SQL textuales y / o construcciones de expresiones SQL sin la participación de los servicios de gestión de nivel superior del ORM, el motor y la conexión son el rey (¿y la reina?). Siga leyendo.