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

87

Я совершенно новичок в модуле 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?

Теги:
sqlite3
cursor

5 ответов

49

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

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

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

А также:

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

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

  • 6
    +1 за признание (поначалу) очень запутанного различия между «традиционными» курсорами БД и курсорами, используемыми для БД в Python
  • 0
    На самом деле, можно просто создать таблицу даже без использования курсора .
31

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

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

  • 5
    Также стоит иметь в виду: PEP 249 не определяет execute для объекта подключения, это расширение sqlite3 .
  • 3
    Он по-прежнему работает с инструкциями SELECT: pastebin.com/5ZbhfEn7 . Причина в том, что вы не вызываете какие-либо методы .fetchXXXX для объекта соединения, вы вызываете метод .fetchXXXX для объекта, возвращаемого методом соединения .execute ().
Показать ещё 7 комментариев
26

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

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

10

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 и быть "эффективным".

0

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню