Performing raw SQL queries¶
Sinta-se livre para escrever consultas SQL nos métodos de seus modelos e métodos
a nível de módulo. O objeto django.db.connection
representa a conexão
atual com o banco de dados, e django.db.transaction
representa
a transação atual do banco de dados. Para usá-lo, chame connection.cursor()
para
capturar o objeto cursor. Então, chame cursor.execute(sql, [params])
para
executar o SQL e cursor.fetchone()
ou cursor.fechall()
para retornar o
resultado em linhas. Após performar a operação que modica os dados, você deve então chamar
transaction.commit_unless_managed()
para garantir que as mudanças estejam confirmadas
no banco de dados. Se sua consulta é puramente uma operção de leitura de dados, nenhum commit
é requerido. Por exemplo:
def my_custom_sql(self):
from django.db import connection, transaction
cursor = connection.cursor()
# Operação de modificação de dado - commit obrigatório
cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
transaction.commit_unless_managed()
# Operação de recebimento de dado - não é necessário o commit
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
row = cursor.fetchone()
return row
Transações e SQL puro¶
Se você está usando decoradores de transações (como commit_on_success
) para
envolver seus views e prover controle de transações, você não terá que fazer uma
chamada manual para transaction.commit_unless_managed()
– você pode comitar
manualmente se você quiser, mas você não será obrigado, desde que o decorador
commita por você. No entanto, se você não comitar manualmente suas mudanças,
você terá de marcar, manualmente, a transação como suja, usando
transaction.set_dirty()
:
@commit_on_success
def my_custom_sql_view(request, value):
from django.db import connection, transaction
cursor = connection.cursor()
# Operação de modificação de dado
cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [value])
# Se nós modificamos dados, marcamos a trasação como suja
transaction.set_dirty()
# Operação de recebimento de dado. Isso não suja a transação,
# então não é obrigatório chamar set_dirty()
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [value])
row = cursor.fetchone()
return render_to_response('template.html', {'row': row})
A chamada para set_dirty()
é feita automaticamente quando você usa o ORM do
Django para fazer moficações no banco de dados. Entretanto, quando você usa um
SQL puro, o Django não tem como sber se seu SQL modifica dados ou não. A chamada
manual set_dirty()
assegura que o Django saiba que estes são dados
modificados que devem ser comitados.
Connections e cursors¶
connection
e cursor
maioritariamente implementa a
DB-API padrão do Python (exceto quando se trata de manipulação de
transações). Se você não está familiarizado com a
DB-API do Python, note que a consulta SQL em cursor.execute()
possui
marcadores, "%s"
, ao invés de adicionar paramêtros diretamente dentro do SQL.
Se você usa esta técnica, as bibliotecas de banco de dados subjacentes irão
automaticamente addicionar aspas e espacar seus paramêtros quando necessário.
(Também atente que o Django espera pelo marcador "%s"
, não pelo marcador
"?"
, que é utilizado pelos bindings para Python do SQLite. Isto é por uma
questão de coerência e bom senso.)
Um lembrete final: Se tudo que você quer é fazer uma clausula WHERE
customizada, você pode somente usar os argumentos where
, tables
e
params
da API padrão.