在Python中使用sqlite是否需要关闭游标?

use*_*946 36 python sqlite

这是场景.在您的函数中,您使用游标执行语句,但其中一个失败并抛出异常.在关闭正在使用的光标之前,您的程序退出该函数.光标是否会占用空间?我必须关闭光标吗?

另外,Python文档中有一个游标使用示例,并说:"如果完成游标,我们也可以关闭游标." 关键字是"可以",而不是"必须".这是什么意思呢?

Mic*_*and 19

这可能是一个好主意(虽然它与sqlite无关,但不知道那里,但它会使你的代码更加便携).此外,使用最近的Python(2.5+),它很容易:

from __future__ import with_statement
from contextlib import closing

with closing(db.cursor()) as cursor:
    # do some stuff
Run Code Online (Sandbox Code Playgroud)


Ben*_*mes 9

你没有义务打电话close(); 它可以像任何其他对象一样被垃圾收集.

但即使等待垃圾收集听起来没问题,我认为仍然可以确保数据库游标等资源无论是否存在异常都是好的方式.


Sim*_*ter 7

我还没有看到对sqlite3.Cursor.close()手术有任何影响.

关闭后,您仍然可以调用fetch(all|one|many)哪个将返回上一个execute语句的剩余结果.即使跑步Cursor.execute()仍然有效......


Pee*_*eer 7

全部,

我使用 sqlite3 的代码(Python 3.8)逐渐出现内存泄漏。我将可能的原因追溯到我的数据库类。事实证明,我会打开并使用游标,但从未关闭它。数据库在程序(Windows 服务)的生命周期内保持打开状态,并在退出时关闭。

一旦我开始关闭所有使用它们的数据库操作中的游标,我的内存泄漏就停止了,内存占用变得稳定。

因此,我建议您花时间关闭游标。它使代码更加一致,显然有助于控制消耗的内存。

这是我如何关闭光标的示例:

def write_to_db(self, cache_item:CacheEntry):
        '''Write a single cache entry to the database'''
        crsr = self._db_con.cursor()

        # Load some data elements
        fax_line_path = cache_item._dir_part
        phone_line = cache_item._phone_line
        sub_folder = cache_item._subfolder
        fname = cache_item._fname
        work_done = cache_item.get_workdone()

        try:
            crsr.execute(FilenameCacheDB.INSERT_CACHE,
                             (fax_line_path, 
                              phone_line, 
                              sub_folder, 
                              fname, 
                              work_done))

        except Exception as e:
            LOG.warning(f"Could not write {cache_item} to db because {e}")
            raise e

        finally:
            #
            # I was *not* closing the cursor prior
            #
            crsr.close()
            self._db_con.commit()
Run Code Online (Sandbox Code Playgroud)


Cra*_*een 5

有趣的是,Python 3.0文档说“如果完成操作,我们也可以关闭游标”,而Python 2.73.6文档说:“完成后也可以关闭连接 ”。

Python 2.7和3.0-3.4文档未描述游标.close()方法。但是Python 3.5和3.6文档描述了cursor.close()方法:

立即关闭光标(而不是在任何时候__del__调用)。

从现在开始,光标将无法使用。一ProgrammingError,如果任何操作试图用光标将引发异常。


sta*_*010 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)
Run Code Online (Sandbox Code Playgroud)

  • 为什么我不能只使用 `with con.cursor() ascursor: ...`?那会更容易阅读..这段代码感觉有点像用java编程..嗯/耸肩 (3认同)