Uma visão geral de uma linha:
O comportamento do execute()
é o mesmo em todos os casos, mas eles são 3 métodos diferentes, em Engine
, Connection
e Session
classes.
O que exatamente é execute()
:
Para entender o comportamento execute()
, precisamos olhar para a Executable
classe. Executable
é uma superclasse para todos os tipos de objetos "instrução", incluindo selecionar (), excluir (), atualizar (), inserir (), texto () - nas palavras mais simples possíveis, um Executable
é um construto de expressão SQL suportado no SQLAlchemy.
Em todos os casos, o execute()
método utiliza o texto SQL ou a expressão SQL construída, ou seja, qualquer uma das várias construções de expressão SQL suportadas no SQLAlchemy e retorna os resultados da consulta (a ResultProxy
- Envolve um DB-API
objeto cursor para fornecer acesso mais fácil às colunas da linha.)
Para esclarecer melhor (apenas para esclarecimentos conceituais, não uma abordagem recomendada) :
Além de Engine.execute()
(execução sem conexão),, Connection.execute()
e Session.execute()
, também é possível usar o execute()
diretamente em qualquer Executable
construção. A Executable
classe possui sua própria implementação execute()
- Conforme a documentação oficial, uma descrição de linha sobre o que execute()
faz é " Compilar e executar issoExecutable
". Nesse caso, precisamos vincular explicitamente o Executable
(construto de expressão SQL) a um Connection
objeto ou, Engine
objeto (que obtém implicitamente um Connection
objeto), para que execute()
você saiba onde executar o SQL
.
O exemplo a seguir demonstra bem isso - Dada uma tabela como abaixo:
from sqlalchemy import MetaData, Table, Column, Integer
meta = MetaData()
users_table = Table('users', meta,
Column('id', Integer, primary_key=True),
Column('name', String(50)))
Execução explícita, ou seja Connection.execute()
- passar o texto SQL ou a expressão SQL construída para o 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()
Execução explícita sem conexão, isto é Engine.execute()
- passando o texto SQL ou a expressão SQL construída diretamente para o execute()
método do Engine:
engine = create_engine('sqlite:///file.db')
result = engine.execute(users_table.select())
for row in result:
# ....
result.close()
A execução implícita, ie Executable.execute()
-, também é sem conexão e chama o execute()
método do Executable
, isto é, chama o execute()
método diretamente na SQL
construção da expressão (uma instância de Executable
) em si.
engine = create_engine('sqlite:///file.db')
meta.bind = engine
result = users_table.select().execute()
for row in result:
# ....
result.close()
Nota: Indique o exemplo implícito de execução para fins de esclarecimento - este modo de execução não é altamente recomendado - conforme os documentos :
"Execução implícita" é um padrão de uso muito antigo que, na maioria dos casos, é mais confuso do que útil, e seu uso é desencorajado. Ambos os padrões parecem incentivar o uso excessivo de "atalhos" convenientes no design de aplicativos, o que leva a problemas mais tarde.
Suas perguntas:
Pelo que entendi, se alguém usar o engine.execute, cria conexão, abre a sessão (a Alquimia se preocupa com você) e executa a consulta.
Você está certo quanto à parte "se alguém usá- engine.execute
lo cria connection
", mas não para "abre session
(a Alquimia se preocupa com você) e executa a consulta" - Usando Engine.execute()
e Connection.execute()
é (quase) a mesma coisa, formal, o Connection
objeto é criado implicitamente e, posteriormente, instanciamos explicitamente. O que realmente acontece neste caso é:
`Engine` object (instantiated via `create_engine()`) -> `Connection` object (instantiated via `engine_instance.connect()`) -> `connection.execute({*SQL expression*})`
Mas existe uma diferença global entre essas três maneiras de executar essa tarefa?
Na camada DB, é exatamente a mesma coisa, todos eles estão executando SQL (expressão de texto ou várias construções de expressão SQL). Do ponto de vista do aplicativo, existem duas opções:
- Execução direta - usando
Engine.execute()
ouConnection.execute()
- Usando
sessions
- eficiente lida transação como única unidade-de-obra, com facilidade via session.add()
, session.rollback()
, session.commit()
, session.close()
. É a maneira de interagir com o banco de dados no caso de ORM, ou seja, tabelas mapeadas. Fornece identity_map para obter instantaneamente objetos já acessados ou recém-criados / adicionados durante uma única solicitação.
Session.execute()
em última análise, usa o Connection.execute()
método de execução de instrução para executar a instrução SQL. Usar Session
objeto é a maneira recomendada do SQLAlchemy ORM para um aplicativo interagir com o banco de dados.
Um trecho dos documentos :
É importante observar que, ao usar o SQLAlchemy ORM, esses objetos geralmente não são acessados; em vez disso, o objeto Session é usado como interface para o banco de dados. No entanto, para aplicativos criados com base no uso direto de instruções SQL textuais e / ou construções de expressão SQL sem o envolvimento dos serviços de gerenciamento de nível superior do ORM, o Mecanismo e a Conexão são o rei (e a rainha?) - continue lendo.