Зарегистрируйтесь, чтобы продолжить обучение

Курсор Python: SQL

С результатом запроса мы взаимодействуем через объект cursor, который можно получить через метод cursor() объекта соединения.

# получение объекта курсора
cursor = conn.cursor()

Для получения результата после выполнения запроса используются следующие команды:

  • cursor.fetchone() — вернуть одну строку
  • cursor.fetchall() — вернуть все строки
  • cursor.fetchmany(size=10) — вернуть указанное количество строк
curs.execute("SELECT * FROM users;")
all_users = curs.fetchall()

Также курсоры итерируемы, так что получить результаты запросов можно обходом.

curs.execute("SELECT * FROM users;")
for row in curs:
    print(row)

Курсоры привязаны к соединению на весь срок жизни, и все команды выполняются в контексте одной сессии базы данных, обернутой соединением. Любые изменения, сделанные в базе данных одним курсором, немедленно видны другим курсорам. Потому хорошей практикой при работе с базой данных является закрытие курсора и соединения с базой. Для автоматизации этого процесса удобно взаимодействовать через контекстный менеджер, используя конструкцию with :

with conn.cursor() as curs:
    curs.execute("SELECT * FROM users;")
    all_users = curs.fetchall()

Фабрика

По умолчанию результат возвращается в виде кортежа. Такое поведение возможно изменить, передав параметр cursor_factory в момент открытия объекта cursor. Так вместо обычного курсора вернется его подкласс с новыми возможностями.

Наиболее полезные подклассы курсоров:

  • RealDictCursor - возвращает данные в виде словаря
  • NamedTupleCursor - возвращает данные в виде именованного кортежа, более легковесной альтернативы словарю
  • LoggingCursor - логгирует все запросы в файл или объект логгера
from psycopg2.extras import NamedTupleCursor

with conn.cursor(cursor_factory=NamedTupleCursor) as curs:
    curs.execute("SELECT * FROM users WHERE name=%s;", ("Alfred",))
    alfred = curs.fetchone()
    alfred  # (id=10, name='Alfred', age='90')

Серверные курсоры

Когда выполняется запрос к базе данных, курсор получает все записи, возвращаемые базой, бэкендом, передавая их в клиентский процесс. Если запрос возвращает большое количество данных, то и будет выделен пропорционально большой объем памяти на стороне клиента.

Если набор данных слишком велик для практической обработки на стороне клиента, то можно создать курсор на стороне сервера. Используя такой курсор, можно передавать клиенту только контролируемое количество данных, не храня весь объем полностью в памяти.

В Psycopg2 серверные курсоры называются именованными курсорами. Именованный курсор создается с помощью метода cursor() с указанием параметра name. Такой курсор ведет себя как обычный курсор, позволяя пользователю перемещаться по набору данных с помощью метода scroll() и читать данные с помощью методов fetchone()и fetchmany(). По умолчанию можно перемещаться только вперед, но если вам нужно перемещаться назад, нужно объявить ваш курсор scrollable.

with conn.cursor(name="cursor_name", scrollable=True) as curs:
    curs.execute("SELECT * FROM users;")
    result = curs.fetchall()

Самостоятельная работа

Выполните шаги из урока у себя на компьютере.

Попробуйте использовать NamedTupleCursor.

Подготовьте запрос, содержащий агрегирующую функцию, например такой:

SELECT MAX(id) from users;

Выполните его и получите результат из именованного кортежа.


Дополнительные материалы

  1. Подклассы курсора
  2. Серверный курсор

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff