Я совершенно новичок в модуле 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
?
Мне кажется, что это неправильная абстракция. Курсор db - это абстракция, предназначенная для обхода набора данных.
Материал из Википедии по теме:
В информатике и технологии курсор базы данных представляет собой структуру управления, которая позволяет обходить записи в базе данных. Курсоры облегчают последующую обработку в сочетании с обходом, таким как извлечение, добавление и удаление записей базы данных. Курсор базы данных, характерный для обхода, делает курсоры похожими на концепцию итератора языка программирования.
А также:
Курсоры могут использоваться не только для извлечения данных из СУБД в приложение, но также для определения строки в таблице, которая должна быть обновлена или удалена. Стандарт SQL: 2003 определяет позиционированное обновление и позиционирует удаление SQL-операторов для этой цели. Такие утверждения не используют регулярное предложение WHERE с предикатами. Вместо этого курсор идентифицирует строку. Курсор должен быть открыт и уже помещен в строку с помощью инструкции FETCH.
Если вы проверите документы на модуле sqlite Python, вы увидите, что cursor
модуля python необходим даже для оператора CREATE TABLE
, поэтому он используется для случаев, когда достаточно простого объекта connection
- как правильно указано OP. Такая абстракция отличается от того, что люди понимают под курсором db и, следовательно, путаницы/разочарования со стороны пользователей. Независимо от эффективности, это просто концептуальные накладные расходы. Было бы неплохо, если бы в документах указывалось, что cursor
модуля python отличается от курсора в SQL и базах данных.
Вам нужен объект-курсор для получения результатов. Ваш пример работает, потому что он INSERT
и, следовательно, вы не пытаетесь получить от него какие-либо строки, но если вы посмотрите на sqlite3
docs, вы 'заметим, что на объектах соединения не существует методов .fetchXXXX
, поэтому, если вы попытались сделать SELECT
без курсора, у вас не получилось бы получить результирующие данные.
Объекты курсора позволяют вам отслеживать, какой результирующий набор является тем, который, поскольку он может запускать несколько запросов, прежде чем вы сделаете выборку результатов первого.
execute
для объекта подключения, это расширение sqlite3
.
Согласно официальным документам connection.execute()
является нестандартным ярлыком, который создает промежуточный объект курсора:
Connection.execute
Это нестандартный ярлык, который создает объект курсора, вызывая метод cursor(), вызывает метод курсоров execute() с указанными параметрами и возвращает курсор.
12.6.8. Использование sqlite3 эффективно
12.6.8.1. Использование методов быстрого доступа
Использование нестандартного
execute()
,executemany()
иexecutescript()
метода объекта Connection, ваш код может быть написан более кратким Ly, потому что вы не должны создавать (часто лишние) Cursor объектов в явном виде. Вместо этого объекты курсора создаются неявно, и эти методы ярлыков возвращают объекты курсора. Таким образом, вы можете выполнить оператор SELECT и перебрать его напрямую, используя только один вызов объекта Connection.
(документация sqlite3, акцент мой.)
Почему бы просто не использовать объект соединения?
Поскольку эти методы объекта соединения нестандартны, то есть они не являются частью спецификации API Python Database Specification v2.0 (PEP 249).
До тех пор, пока вы используете стандартные методы объекта Cursor, вы можете быть уверены, что если вы переключитесь на другую реализацию базы данных, которая следует за вышеуказанной спецификацией, ваш код будет полностью переносимым. Возможно, вам нужно будет только изменить линию import
.
Но если вы используете connection.execute
есть вероятность, что переключение не будет таким простым. Вот основные причины, по которым вы, возможно, захотите использовать cursor.execute
.
Однако, если вы уверены, что не собираетесь переключаться, я бы сказал, что вполне нормально использовать ярлык connection.execute
и быть "эффективным".
Это дает нам возможность иметь несколько отдельных рабочих сред через одно и то же соединение с базой данных.