Зачем вам нужно создавать курсор при запросе базы данных sqlite?

Я совершенно новичок в модуле sqlite3 Python (и вообще SQL в этом случае), и это просто полностью пень. Обильное отсутствие описаний объектов cursor (скорее, их необходимость) также кажется странным.

Этот фрагмент кода является предпочтительным способом:

import sqlite3
conn = sqlite3.connect("db.sqlite")
c = conn.cursor()
c.execute('''insert into table "users" values ("Jack Bauer", "555-555-5555")''')
conn.commit()
c.close()

Этого нет, хотя он работает так же хорошо и без (казалось бы, бессмысленного) cursor:

import sqlite3
conn = sqlite3.connect("db.sqlite")
conn.execute('''insert into table "users" values ("Jack Bauer", "555-555-5555")''')
conn.commit()

Может ли кто-нибудь сказать мне, зачем мне cursor?
Это просто кажется бессмысленным накладные расходы. Для каждого метода в моем скрипте, который обращается к базе данных, я должен создать и уничтожить cursor?
Почему бы просто не использовать объект connection?

Ответ 1

Мне кажется, что это неправильная абстракция. Курсор db - это абстракция, предназначенная для обхода набора данных.

Материал из Википедии по теме:

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

А также:

Курсоры могут использоваться не только для извлечения данных из СУБД в приложение, но также для определения строки в таблице, которая должна быть обновлена или удалена. Стандарт SQL: 2003 определяет позиционированное обновление и позиционирует удаление SQL-операторов для этой цели. Такие утверждения не используют регулярное предложение WHERE с предикатами. Вместо этого курсор идентифицирует строку. Курсор должен быть открыт и уже помещен в строку с помощью инструкции FETCH.

Если вы проверите документы на модуле sqlite Python, вы увидите, что cursor модуля python необходим даже для оператора CREATE TABLE, поэтому он используется для случаев, когда достаточно простого объекта connection - как правильно указано OP. Такая абстракция отличается от того, что люди понимают под курсором db и, следовательно, путаницы/разочарования со стороны пользователей. Независимо от эффективности, это просто концептуальные накладные расходы. Было бы неплохо, если бы в документах указывалось, что cursor модуля python отличается от курсора в SQL и базах данных.

Ответ 2

Вам нужен объект-курсор для получения результатов. Ваш пример работает, потому что он INSERT и, следовательно, вы не пытаетесь получить от него какие-либо строки, но если вы посмотрите на sqlite3 docs, вы 'заметим, что на объектах соединения не существует методов .fetchXXXX, поэтому, если вы попытались сделать SELECT без курсора, у вас не получилось бы получить результирующие данные.

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

Ответ 3

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

Connection.execute
Это нестандартный ярлык, который создает объект курсора, вызывая метод cursor(), вызывает метод курсоров execute() с указанными параметрами и возвращает курсор.

Ответ 4

12.6.8. Эффективное использование sqlite3

12.6.8.1. Использование ярлыков

Использование нестандартного execute(), executemany() и executescript() метода объекта Connection, ваш код может быть написан более кратким Ly, потому что вы не должны создавать (часто лишние) Cursor объектов в явном виде. Вместо этого объекты Cursor создаются неявно, и эти методы быстрого вызова возвращают объекты курсора. Таким образом, вы можете выполнить инструкцию SELECT и выполнить итерацию по ней напрямую, используя только один вызов объекта Connection.

(документация sqlite3; выделение мое.)

Почему бы просто не использовать объект подключения?

Поскольку эти методы объекта соединения являются нестандартными, то есть они не являются частью спецификации API базы данных Python v2.0 (PEP 249).

Пока вы используете стандартные методы объекта Cursor, вы можете быть уверены, что если вы переключитесь на другую реализацию базы данных, соответствующую приведенной выше спецификации, ваш код будет полностью переносимым. Возможно, вам нужно будет только изменить строку import.

Но если вы используете connection.execute есть вероятность, что переключение не будет таким простым. Это основная причина, по которой вы можете использовать вместо этого cursor.execute.

Однако, если вы уверены, что не собираетесь переключаться, я бы сказал, что все в порядке, чтобы использовать ярлык connection.execute и быть "эффективным".

Ответ 5

Это дает нам возможность иметь несколько отдельных рабочих сред через одно и то же соединение с базой данных.