ZetCode

Python sqlite3.Cursor.close 方法

上次修改时间:2025 年 4 月 15 日

这篇综合指南探讨了 Python 的 sqlite3.Cursor.close 方法,该方法对于正确的数据库资源管理至关重要。我们将通过实际示例介绍其目的、使用模式和最佳实践。

基本定义

sqlite3.Cursor.close 方法关闭游标,释放任何相关的资源。一旦关闭,游标将无法用于进一步的操作。

主要特点:它是幂等的(可以安全地调用多次),释放数据库锁,并有助于防止资源泄漏。正确的游标管理对于数据库应用程序至关重要。

基本游标关闭

此示例演示了在传统的 try-finally 块中使用 Cursor.close 的基本用法,以确保清理。

basic_close.py
import sqlite3

conn = sqlite3.connect('example.db')
cursor = conn.cursor()

try:
    cursor.execute("SELECT * FROM users")
    for row in cursor:
        print(row)
finally:
    cursor.close()  # Explicitly close the cursor
    conn.close()

游标在 finally 块中关闭,以确保即使在执行期间发生异常也会发生。此模式保证资源清理。

虽然现代 Python 经常使用上下文管理器,但了解显式关闭对于遗留代码或自定义资源管理场景非常重要。

使用带有上下文管理器的游标

游标可以用作上下文管理器,以便自动清理。这是现代 Python 代码中推荐的方法。

context_manager.py
import sqlite3

with sqlite3.connect('example.db') as conn:
    with conn.cursor() as cursor:  # Cursor as context manager
        cursor.execute("SELECT name, age FROM users")
        print(cursor.fetchall())
    # Cursor automatically closed here
# Connection automatically closed here

with 语句确保在块退出时正确关闭连接和游标,即使发生错误也是如此。 这更简洁、更安全。

嵌套上下文管理器优雅地处理连接和游标清理。内部游标上下文首先关闭,然后是连接上下文。

具有上下文管理器的多个游标

此示例展示了如何在单个连接中使用上下文管理器管理多个游标。

multiple_cursors.py
import sqlite3

with sqlite3.connect('inventory.db') as conn:
    with conn.cursor() as items_cursor:
        items_cursor.execute("SELECT * FROM items")
        items = items_cursor.fetchall()
    
    with conn.cursor() as sales_cursor:
        sales_cursor.execute("SELECT * FROM sales")
        sales = sales_cursor.fetchall()
    
    print(f"Total items: {len(items)}, Total sales: {len(sales)}")

每个游标都在自己的上下文块中进行管理,确保使用后正确清理。 连接保持打开状态以进行所有操作,直到外部块退出。

当您需要用于不同查询的单独游标,但又想维护单个事务范围时,此模式非常有用。

带有错误处理的游标关闭

此示例演示了在面对潜在错误时正确的游标清理。

error_handling.py
import sqlite3

try:
    conn = sqlite3.connect('example.db')
    cursor = conn.cursor()
    
    cursor.execute("SELECT * FROM non_existent_table")
    results = cursor.fetchall()
    
except sqlite3.Error as e:
    print(f"Database error: {e}")
finally:
    if 'cursor' in locals():
        cursor.close()  # Ensure cursor is closed
    if 'conn' in locals():
        conn.close()    # Ensure connection is closed

finally 块在尝试关闭资源之前检查资源是否存在。 如果连接或游标创建失败,这将防止 AttributeError。

具有正确清理的强大错误处理对于生产数据库应用程序至关重要,可以防止资源泄漏。

函数中的游标关闭

此示例显示了在返回数据的函数中正确的游标管理。

function_close.py
import sqlite3

def get_user_count():
    conn = sqlite3.connect('users.db')
    cursor = conn.cursor()
    try:
        cursor.execute("SELECT COUNT(*) FROM users")
        count = cursor.fetchone()[0]
        return count
    finally:
        cursor.close()
        conn.close()

print(f"Total users: {get_user_count()}")

该函数确保在返回之前关闭游标和连接,即使发生错误也是如此。 这可以防止在调用该函数时出现资源泄漏。

对于使用数据库的函数,请始终在返回之前清理资源,以避免留下打开的连接或游标。

带有连接池的游标关闭

此高级示例演示了带有连接池的游标管理。

connection_pool.py
import sqlite3
from contextlib import contextmanager

@contextmanager
def db_connection():
    conn = sqlite3.connect('app.db', timeout=10.0)
    try:
        yield conn
    finally:
        conn.close()

@contextmanager
def db_cursor(conn):
    cursor = conn.cursor()
    try:
        yield cursor
    finally:
        cursor.close()

# Usage:
with db_connection() as conn:
    with db_cursor(conn) as cursor:
        cursor.execute("UPDATE stats SET visits = visits + 1")
        conn.commit()

此示例为连接和游标管理创建可重用的上下文管理器。 嵌套结构确保正确的清理顺序。

像这样的连接池模式在处理许多数据库操作的 Web 应用程序或服务中非常有用。

带有行工厂的游标关闭

此示例将游标管理与行工厂配置结合起来。

row_factory.py
import sqlite3

with sqlite3.connect('products.db') as conn:
    conn.row_factory = sqlite3.Row  # Enable named column access
    with conn.cursor() as cursor:
        cursor.execute("SELECT id, name, price FROM products")
        for row in cursor:
            print(f"{row['id']}: {row['name']} (${row['price']:.2f})")

游标继承连接的行工厂设置。 上下文管理器确保在使用后正确关闭连接和游标。

使用 sqlite3.Row 提供命名列访问,同时通过上下文管理器保持正确资源清理的优势。

最佳实践

资料来源

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。 我自 2007 年以来一直在撰写编程文章。 迄今为止,我撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 Python 教程