Python sqlite3.Cursor.fetchmany 方法
上次修改时间:2025 年 4 月 15 日
本综合指南探讨了 Python 的 sqlite3.Cursor.fetchmany 方法,该方法用于从数据库查询结果中检索多行数据。我们将介绍基本用法、参数、内存效率和实际示例。
基本定义
fetchmany 方法从查询结果中检索下一组行。它返回一个元组列表,其中每个元组代表数据库中的一行。
主要特性:它接受一个 size 参数来控制要获取的行数,对于大型结果集具有内存效率,并且在调用之间保持游标位置。它非常适合查询结果的批量处理。
fetchmany 的基本用法
这是 fetchmany 最简单的用法,可以批量检索行。
import sqlite3
with sqlite3.connect('example.db') as conn:
conn.execute("CREATE TABLE IF NOT EXISTS products (id INTEGER, name TEXT)")
conn.executemany("INSERT INTO products VALUES (?, ?)",
[(1, 'Laptop'), (2, 'Phone'), (3, 'Tablet'),
(4, 'Monitor'), (5, 'Keyboard')])
cursor = conn.cursor()
cursor.execute("SELECT * FROM products")
# Fetch first 2 rows
batch1 = cursor.fetchmany(2)
print("Batch 1:", batch1)
# Fetch next 2 rows
batch2 = cursor.fetchmany(2)
print("Batch 2:", batch2)
# Fetch remaining rows (1 in this case)
batch3 = cursor.fetchmany(2)
print("Batch 3:", batch3)
此示例显示了基本批量获取。我们插入 5 行,然后分 2 行一批地获取它们。游标在调用之间保持位置。
输出将显示前两个产品,然后是接下来的两个产品,然后是剩下的一个产品。当没有更多行可用时,该方法返回一个空列表。
使用默认大小进行获取
当未指定大小 (size) 时,fetchmany 使用游标的 arraysize。
import sqlite3
with sqlite3.connect('example.db') as conn:
cursor = conn.cursor()
# Set the default fetch size
cursor.arraysize = 3
cursor.execute("SELECT * FROM products")
# Fetch using default size
batch = cursor.fetchmany()
print("First batch (size 3):", batch)
# Change size and fetch again
cursor.arraysize = 1
batch = cursor.fetchmany()
print("Second batch (size 1):", batch)
这演示了当未提供 size 参数时,arraysize 如何影响 fetchmany。第一次获取得到 3 行,第二次获取得到 1 行。
当您希望在整个应用程序中始终使用相同的提取大小时,设置 arraysize 非常有用。
处理大型结果集
fetchmany 非常适合处理大型结果集,而无需将所有内容都加载到内存中。
import sqlite3
def process_large_table():
with sqlite3.connect('large_db.db') as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM big_table")
while True:
batch = cursor.fetchmany(100) # Process 100 rows at a time
if not batch:
break
# Process the batch
for row in batch:
process_row(row)
def process_row(row):
# Simulate row processing
print(f"Processing row {row[0]}")
# Create sample large database
with sqlite3.connect('large_db.db') as conn:
conn.execute("CREATE TABLE big_table AS SELECT value as id, 'Data ' || value as info FROM generate_series(1, 1000)")
process_large_table()
这种模式对于处理大型数据集至关重要。它以易于管理的块来获取行,并在获取下一批之前处理每个批次。
while 循环会一直持续到 fetchmany 返回一个空列表,表明已处理完所有行。
与 fetchone 结合使用
fetchmany 可以与 fetchone 结合使用,以实现灵活的结果处理。
import sqlite3
with sqlite3.connect('example.db') as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM products ORDER BY id")
# Get first row individually
first_row = cursor.fetchone()
print("First product:", first_row)
# Then get next 2 rows as a batch
next_rows = cursor.fetchmany(2)
print("Next two products:", next_rows)
# Then get one more row
another_row = cursor.fetchone()
print("Another product:", another_row)
此示例显示了混合提取样式。我们使用 fetchone 获取第一行,然后使用 fetchmany 获取一批,然后再获取单行。
游标在所有提取方法中始终如一地保持位置,从而允许灵活的结果处理。
空结果处理
fetchmany 能够优雅地处理空结果集和部分提取。
import sqlite3
with sqlite3.connect('example.db') as conn:
cursor = conn.cursor()
# Query with no results
cursor.execute("SELECT * FROM products WHERE id = 999")
empty_result = cursor.fetchmany(5)
print("Empty result:", empty_result) # []
# Query with fewer results than requested
cursor.execute("SELECT * FROM products LIMIT 3")
partial_result = cursor.fetchmany(5)
print("Partial result (3 rows):", partial_result)
# Subsequent fetch returns empty list
next_result = cursor.fetchmany(2)
print("After exhaustion:", next_result) # []
这演示了 fetchmany 在空或小结果集中的行为。当没有行可用时,它返回一个空列表。
当存在的行数少于请求的行数时,它会返回所有可用行而不会出错。后续调用返回空列表。
与行工厂一起使用
fetchmany 与行工厂一起使用以返回自定义的行格式。
import sqlite3
with sqlite3.connect('example.db') as conn:
# Use built-in Row factory
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
cursor.execute("SELECT * FROM products")
batch = cursor.fetchmany(2)
# Access rows by column name
for row in batch:
print(f"Product {row['id']}: {row['name']}")
print("Columns:", row.keys())
此示例显示了带有 sqlite3.Row 工厂的 fetchmany。可以通过列名或索引访问行。
keys 方法显示可用的列名,使结果比普通元组更具自描述性。
错误处理
正确的错误处理确保了使用 fetchmany 进行的健壮的数据库操作。
import sqlite3
try:
with sqlite3.connect('example.db') as conn:
cursor = conn.cursor()
# Invalid query (no such table)
cursor.execute("SELECT * FROM non_existent_table")
batch = cursor.fetchmany(2)
except sqlite3.Error as e:
print("Database error:", e)
finally:
print("Operation attempted")
这显示了处理在提取操作期间可能发生的错误。with 语句确保正确的连接清理。
常见的错误包括无效的 SQL、缺少表或数据库访问错误。始终在生产代码中处理这些情况。
最佳实践
- 使用适当的批量大小: 平衡内存和往返次数
- 始终检查空结果: 处理数据结束的情况
- 与上下文管理器结合使用: 确保资源清理
- 考虑内存效率: 使用 fetchmany 处理大型结果
- 维护游标状态: 注意调用之间的位置
资料来源
作者
列出所有 Python 教程。