这是场景.在您的函数中,您使用游标执行语句,但其中一个失败并抛出异常.在关闭正在使用的光标之前,您的程序退出该函数.光标是否会占用空间?我必须关闭光标吗?
另外,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)
我还没有看到对sqlite3.Cursor.close()手术有任何影响.
关闭后,您仍然可以调用fetch(all|one|many)哪个将返回上一个execute语句的剩余结果.即使跑步Cursor.execute()仍然有效......
全部,
我使用 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)
有趣的是,Python 3.0文档说“如果完成操作,我们也可以关闭游标”,而Python 2.7和3.6文档说:“完成后也可以关闭连接 ”。
Python 2.7和3.0-3.4文档未描述游标.close()方法。但是Python 3.5和3.6文档描述了cursor.close()方法:
立即关闭光标(而不是在任何时候
__del__调用)。从现在开始,光标将无法使用。一
ProgrammingError,如果任何操作试图用光标将引发异常。
此代码将自动关闭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)
| 归档时间: |
|
| 查看次数: |
16721 次 |
| 最近记录: |