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
и т.д.
Слабым местом метода 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)