Executando instruções SQL no Django
O Django converte automaticamente os métodos de QuerySet em instruções SQL correspondentes, que são então executadas no banco de dados. No entanto, o framework também permite definir e executar consultas SQL diretamente por meio do método raw()
, que recebe a consulta SQL como argumento:
from .models import Person
people = Person.objects.raw("SELECT id, name FROM hello_person")
# Iteração sobre os resultados
for person in people:
print(person.name)
# Acessando um único registro
print(people[0].name)
Nesse caso, o método raw()
recebe uma consulta que retorna os valores dos campos id
e name
da tabela hello_person
. Esse método retorna um objeto django.db.models.query.RawQuerySet
, que pode ser percorrido como um QuerySet
para extrair os dados.
⚠️ É importante considerar que esse método sempre retorna um conjunto de registros e não leva em conta nenhum filtro aplicado antes da chamada a
raw()
:# Aqui, filter() não terá efeito people = Person.objects.filter(age__lt=35).raw("SELECT * FROM hello_person")
Passando parâmetros
O método raw()
permite passar parâmetros para a consulta SQL por meio do argumento params
:
# Definição de valores para os parâmetros
name_for_filter = "Tom"
age_for_filter = 35
people = Person.objects.raw(
"SELECT * FROM hello_person WHERE name = %s OR age > %s",
[name_for_filter, age_for_filter]
)
A consulta SQL acima usa dois parâmetros representados por %s
. O segundo argumento de raw()
é uma lista de valores que substituirão os símbolos %s
na consulta. Os valores são passados na ordem em que aparecem, ou seja, name_for_filter
substituirá o primeiro %s
, e age_for_filter
substituirá o segundo.
Executando instruções SQL
Uma limitação do método raw()
é que ele suporta apenas consultas SELECT
, ou seja, operações que retornam registros. Para executar comandos SQL como UPDATE
, INSERT
, DELETE
, pode ser utilizado django.db.connection
.
O objeto django.db.connection
representa a conexão com o banco de dados:
from django.db import connection
with connection.cursor() as cursor:
cursor.execute("UPDATE hello_person SET name = 'Tomas' WHERE name = 'Tom' AND age = 22")
cursor.execute("SELECT * FROM hello_person WHERE name = 'Tomas'")
row = cursor.fetchone() # Obtendo um único registro
print(row)
Para interagir com o banco, primeiro é necessário obter um cursor com connection.cursor()
. O método cursor.execute()
executa a consulta SQL fornecida. Para recuperar os resultados, são utilizados os métodos cursor.fetchone()
e cursor.fetchall()
.
Também é possível passar parâmetros para as consultas:
from django.db import connection
old_name = "Tomas"
new_name = "Tom"
with connection.cursor() as cursor:
cursor.execute("UPDATE hello_person SET name = %s WHERE name = %s", [new_name, old_name])
cursor.execute("SELECT * FROM hello_person WHERE name = %s", [new_name])
rows = cursor.fetchall() # Obtendo todos os registros
for row in rows:
print(row)
Documentação oficial: