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.