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.