Выполнение SQL-выражений

Последнее обновление: 26.08.2022

Django автоматически транслирует методы QuerySet в соответствующие SQL-выражения, которые затем выполняются в базе данных. Однако фреймворк также позволяет непосредственно определить SQL-запрос и выполнять его. Для этого применяется метод raw(), в который передается SQL-запрос:

from .models import Person 

people = Person.objects.raw("SELECT id, name FROM hello_person")

# перебираем полученные строки
for person in people:
    print(person.name)

# получаем один объект
print(people[0].name)

В данном случае в raw() передается запрос, который получает значения полей id и name из таблицы hello_person. Этот метод возвращает объект django.db.models.query.RawQuerySet, который, подобно QuerySet, также можно перебрать в цикле и извлечь из него данные.

Стоит учитывать, что данный метод должен возвращать набор строк. Также стоит отметить, что метод не учитывает никакие выражения фильтрации, которые идут до его вызова

# здесь filter НЕ окажет никакого влияния
people = Person.objects.filter(age__lt=35).raw("SELECT * FROM hello_person")

Передача параметров

С помощью параметра params в метод raw() можно передать значения для параметров в SQL-запросе:

# определяем значение для параметра name
name_for_filter = "Tom"
# определяем значение для параметра age
age_for_filter = 35

people = Person.objects.raw("SELECT * FROM hello_person WHERE name = %s OR age > %s", 
[name_for_filter, age_for_filter])

В данном случае SQL-запрос использует два параметра, которые определяются через спецсимволы %s. Второй параметр метода raw представляет список аргументов, которые передаются в запрос вместо символов %s. Аргументы передаются по позиции, то есть значение name_for_filter передается на место первого вхождения %s, второе значение - age_for_filter - на место второго вхождения %s и т.д.

Выполнение команд SQL

Слабым местом метода raw() является то, что он позволяет выполнять только команду SELECT, которая возвращает набор строк. Если же мы хотим выполнить другие sql-команды: UPDATE, INSERT или DELETE или другие типы SELECT-запросов, то в этом случае мы можем воспользоваться функционалом django.db.connection.

Объект django.db.connection представляет подключение к базе данных:

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()     # получаем одну строку
        print(row)

Для использования подключения вначале необходимо получить курсор с помощью метода connection.cursor(). А затем у курсора вызывается метод cursor.execute(), в который передается выполняемый sql-запрос. Для возвращения результата применяются методы cursor.fetchone() и cursor.fetchall().

Также можно использовать параметры:

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 = 'Tom'")
        rows = cursor.fetchall()   # получаем все строки
        
        for row in rows:
            print(row)
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850