В Python с sqlite нужно ли закрывать курсор? - PullRequest
32 голосов
/ 25 февраля 2010

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

Кроме того, в документации по Python есть пример использования курсора и сказано: «Мы также можем закрыть курсор, если мы закончили с ним». Ключевое слово «может», а не «должен». Что они имеют в виду именно под этим?

Ответы [ 5 ]

17 голосов
/ 25 февраля 2010

Это, вероятно, хорошая идея (хотя это может не иметь большого значения для sqlite, не знаю, но это сделает ваш код более переносимым). Кроме того, с недавним Python (2.5+) это легко:

from __future__ import with_statement
from contextlib import closing

with closing(db.cursor()) as cursor:
    # do some stuff
8 голосов
/ 25 февраля 2010

Вы не обязаны звонить close() по курсору; это может быть мусор, как любой другой объект.

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

7 голосов
/ 10 марта 2010

Я не видел никакого эффекта для операции sqlite3.Cursor.close().

После закрытия вы все равно можете вызвать fetch(all|one|many), который вернет оставшиеся результаты из предыдущего оператора execute. Даже работает Cursor.execute() все еще работает ...

4 голосов
/ 17 июля 2017

Интересно, что в Python 3.0 doc написано «Мы также можем закрыть курсор, если с ним покончим», тогда как Python 2.7 и 3.6 doc говорит: «Мы также можем закрыть соединение , если с ним покончено».

Документы Python 2.7 и 3.0-3.4 не описывают метод курсора .close(). Но документы Python 3.5 и 3.6 описывают курсор .close() метод:

Закрыть курсор сейчас (а не всякий раз, когда вызывается __del__).

Курсор будет недоступен с этой точки вперед; ProgrammingError будет сгенерировано исключение, если с курсором будет предпринята какая-либо операция.

3 голосов
/ 27 ноября 2017

Этот код автоматически закроет 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...