Python sqlite3.Cursor.execute 方法
上次修改时间:2025 年 4 月 15 日
这份综合指南探讨了 Python 的 sqlite3.Cursor.execute 方法,这是在 SQLite 数据库中执行 SQL 语句的主要方式。我们将涵盖基本用法、参数绑定、事务处理和实际示例。
基本定义
sqlite3.Cursor.execute 方法执行单个 SQL 语句。它将 SQL 查询作为其第一个参数,并将可选参数用于将值绑定到查询。
关键特性:它返回游标对象以进行链式调用,支持参数化查询以保证安全性,并且可以执行任何有效的 SQL 语句。该方法是所有数据库操作的核心。
基本 SQL 执行
这是 execute 最简单的用法,用于创建表和插入数据。该示例使用上下文管理器进行自动资源清理。
import sqlite3
with sqlite3.connect('example.db') as conn:
with conn.cursor() as cursor:
# Create table
cursor.execute('''CREATE TABLE IF NOT EXISTS products
(id INTEGER PRIMARY KEY, name TEXT, price REAL)''')
# Insert data
cursor.execute("INSERT INTO products (name, price) VALUES (?, ?)",
('Laptop', 999.99))
# Commit is automatic with context manager
此示例显示了基本工作流程:连接到数据库,创建游标,执行 SQL 语句。上下文管理器确保正确的资源清理。
INSERT 语句中的 ? 占位符演示了参数化查询,这可以防止 SQL 注入并处理正确的转义值。
参数绑定样式
execute 方法支持不同的参数绑定样式。此示例显示了所有三种支持的格式。
import sqlite3
with sqlite3.connect('example.db') as conn:
with conn.cursor() as cursor:
# Question mark style (positional)
cursor.execute("INSERT INTO products VALUES (?, ?, ?)",
(2, 'Mouse', 19.99))
# Named style
cursor.execute("INSERT INTO products VALUES (:id, :name, :price)",
{'id': 3, 'name': 'Keyboard', 'price': 49.99})
# Numbered style
cursor.execute("INSERT INTO products VALUES (?1, ?2, ?3)",
(4, 'Monitor', 199.99))
conn.commit()
SQLite 支持三种参数绑定样式:问号(位置)、命名和编号。每种方法都有优点,具体取决于用例。
命名参数在包含许多参数的复杂查询中尤其有用,因为它们使代码更具可读性和可维护性。
执行多个语句
executescript 方法允许一次执行多个 SQL 语句。这对于模式初始化或批量操作非常有用。
import sqlite3
sql_script = """
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS customers (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE
);
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY,
customer_id INTEGER,
amount REAL,
FOREIGN KEY (customer_id) REFERENCES customers(id)
);
COMMIT;
"""
with sqlite3.connect('shop.db') as conn:
with conn.cursor() as cursor:
cursor.executescript(sql_script)
此示例在单个事务中创建包含两个相关表的完整数据库模式。 executescript 方法解析并执行整个脚本。
请注意,executescript 在执行之前提交任何挂起的事务,并在执行之后再次提交。它是设置脚本的理想选择。
执行许多语句
executemany 方法使用不同的参数有效地多次执行相同的 SQL 语句。这比单个 executes 执行批量插入要快得多。
import sqlite3
products = [
(5, 'Headphones', 79.99),
(6, 'Webcam', 59.99),
(7, 'Microphone', 89.99),
(8, 'Speaker', 129.99)
]
with sqlite3.connect('example.db') as conn:
with conn.cursor() as cursor:
cursor.executemany("INSERT INTO products VALUES (?, ?, ?)", products)
print(f"Inserted {cursor.rowcount} rows")
此示例在单个高效操作中插入多行。 executemany 方法针对此模式进行了优化。
rowcount 属性返回上次操作影响的行数。 对于 executemany,它显示总受影响的行。
获取结果
执行 SELECT 语句后,可以使用各种方法获取结果。 此示例演示了不同的获取方法。
import sqlite3
with sqlite3.connect('example.db') as conn:
with conn.cursor() as cursor:
# Execute SELECT
cursor.execute("SELECT * FROM products WHERE price > ?", (50,))
# Fetch one row
print("First product over $50:", cursor.fetchone())
# Fetch next 2 rows
print("Next two products:", cursor.fetchmany(2))
# Fetch all remaining rows
print("All remaining products:", cursor.fetchall())
该示例显示了三种获取方法:fetchone 用于单行,fetchmany 用于指定数量的行,以及 fetchall 用于所有剩余的行。
游标维护有关结果集的状态,因此后续的 fetch 调用会从上一个调用停止的位置继续。 这样可以有效地处理大型结果集。
使用行工厂
行工厂允许自定义从查询返回行的方式。 此示例演示如何按名称而不是位置访问列。
import sqlite3
with sqlite3.connect('example.db') as conn:
# Set row factory for named access
conn.row_factory = sqlite3.Row
with conn.cursor() as cursor:
cursor.execute("SELECT name, price FROM products WHERE id = ?", (1,))
product = cursor.fetchone()
# Access columns by name
print(f"{product['name']} costs ${product['price']:.2f}")
# Can still access by index
print(f"Same product: {product[0]} costs ${product[1]:.2f}")
sqlite3.Row 工厂提供基于索引和基于名称的列访问。 这使得代码更具可读性,更能适应模式更改。
Row 对象还支持其他有用的功能,例如字典样式的键访问、keys 方法以及用于调试的正确字符串表示。
错误处理
正确的错误处理对于健壮的数据库应用程序至关重要。 此示例演示了在执行期间处理常见的 SQLite 错误。
import sqlite3
try:
with sqlite3.connect('example.db') as conn:
with conn.cursor() as cursor:
# This will fail (duplicate primary key)
cursor.execute("INSERT INTO products VALUES (1, 'Tablet', 299.99)")
conn.commit()
except sqlite3.IntegrityError as e:
print(f"Integrity error: {e}")
except sqlite3.DatabaseError as e:
print(f"Database error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
该示例显示了如何处理特定的 SQLite 错误,例如违反约束的 IntegrityError。 可以使用 DatabaseError 捕获更一般的错误。
始终适当地处理数据库异常 - 至少记录它们,并经常为可恢复的错误实现重试逻辑或用户通知。
最佳实践
- 使用参数化查询: 始终防止 SQL 注入
- 正确关闭资源: 为连接/游标使用上下文管理器
- 显式处理事务: 根据需要提交或回滚
- 使用适当的提取方法: 根据结果大小需求进行选择
- 实现错误处理: 捕获并处理数据库异常
资料来源
作者
列出所有 Python 教程。