В Python с sqlite необходимо закрыть курсор?
Вот сценарий. В вашей функции вы выполняете инструкции с помощью курсора, но один из них терпит неудачу и генерируется исключение. Ваша программа выходит из функции перед закрытием курсора, с которым она работала. Будет ли курсор перемещаться вокруг места? Мне нужно закрыть курсор?
Кроме того, в документации на Python есть пример использования курсора и сказано: "Мы также можем закрыть курсор, если мы с ним закончим". Ключевое слово "can", а не "must". Что они означают именно этим?
Ответы
Ответ 1
Это, вероятно, хорошая идея (хотя, возможно, это не имеет особого значения для sqlite, не знаю, но это сделает ваш код более портативным). Кроме того, с недавним Python (2.5+), это легко:
from __future__ import with_statement
from contextlib import closing
with closing(db.cursor()) as cursor:
# do some stuff
Ответ 2
Вы не обязаны называть close()
на курсор; это может быть сбор мусора, как любой другой объект.
Но даже если ожидание сборки мусора звучит нормально, я думаю, что было бы хорошим стилем, чтобы гарантировать, что ресурс, такой как курсор базы данных, закрывается независимо от того, есть ли исключение.
Ответ 3
Я еще не видел эффекта для операции sqlite3.Cursor.close()
.
После закрытия вы все равно можете вызвать fetch(all|one|many)
, который вернет остальные результаты из предыдущего оператора выполнения. Даже работает Cursor.execute()
все еще работает...
Ответ 4
Интересно, что Python 3.0 doc говорит: "Мы также можем закрыть курсор, если мы закончили с ним", а Python 2.7 и 3.6 doc говорит: "Мы также можем закрыть соединение, если мы закончили с ним".
Документы Python 2.7 и 3.0-3.4 не описывают метод курсора .close()
. Но в документах Python 3.5 и 3.6 описывается метод cursor .close()
:
Закройте курсор сейчас (а не всякий раз, когда вызывается __del__
).
Курсор будет недоступен с этой точки вперед; a ProgrammingError
exception будет поднят, если любая операция будет предпринята с помощью курсора.
Ответ 5
Этот код автоматически закроет Cursor
. Он также автоматически закрывает и фиксирует Connection
.
import sqlite3
import contextlib
def execute_statement(statement):
with contextlib.closing(sqlite3.connect(path_to_file)) as conn: # auto-closes
with conn: # auto-commits
with contextlib.closing(conn.cursor()) as cursor: # auto-closes
cursor.execute(statement)