ZetCode

Python sqlite3.Connection.execute 方法

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

这份全面的指南探讨了 Python 的 sqlite3.Connection.execute 方法,这是使用 SQLite 数据库执行 SQL 语句的主要方式。

基本定义

execute 方法在数据库连接上执行单个 SQL 语句。为了方便起见,它可以直接在连接对象上使用。

主要特点:它返回一个游标对象,接受参数化查询,并处理 DDL 和 DML 语句。它将游标创建和执行合并为一个步骤。

基本 SQL 执行

以下是使用 execute 创建表并插入数据的最简单用法。

basic_execute.py
import sqlite3

with sqlite3.connect('example.db') as conn:
    # Create table using execute
    conn.execute('''CREATE TABLE IF NOT EXISTS users
                    (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)''')
    
    # Insert data with parameters
    conn.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Alice', 30))
    
    # Commit is automatic with 'with' statement

此示例展示了使用 execute 的基本 CRUD 操作。“with”语句确保正确的资源清理。

建议使用参数化查询(使用 ? 占位符)以防止 SQL 注入并提高重复查询的性能。

查询数据

execute 方法可以运行 SELECT 查询并返回游标对象以进行结果处理。

query_data.py
import sqlite3

with sqlite3.connect('example.db') as conn:
    # Execute query and get cursor
    cursor = conn.execute("SELECT * FROM users WHERE age > ?", (25,))
    
    # Process results
    for row in cursor:
        print(f"ID: {row[0]}, Name: {row[1]}, Age: {row[2]}")

该示例演示了使用参数查询数据。execute 返回的游标是可迭代的。

默认情况下,行数据通过索引访问。我们将在后面的示例中展示命名访问。

多参数执行

executemany 方法(与 execute 相关)有效地处理多个参数集。

executemany.py
import sqlite3

users = [
    ('Bob', 25),
    ('Charlie', 40),
    ('Diana', 35)
]

with sqlite3.connect('example.db') as conn:
    conn.executemany("INSERT INTO users (name, age) VALUES (?, ?)", users)

这比用于批量插入的单个 execute 调用更有效。 事务会自动处理。

用户列表中的每个元组对应于查询的一组参数。

命名参数

SQLite 支持命名参数(使用 :name 语法)以获得更具可读性的查询。

named_params.py
import sqlite3

with sqlite3.connect('example.db') as conn:
    # Using named parameters
    conn.execute("""
        UPDATE users 
        SET age = :new_age 
        WHERE name = :user_name
    """, {'new_age': 32, 'user_name': 'Alice'})
    
    # Verify update
    cursor = conn.execute("SELECT age FROM users WHERE name = ?", ('Alice',))
    print("New age:", cursor.fetchone()[0])

命名参数使查询更具可读性和可维护性,尤其是在有许多参数的情况下。

参数字典键必须与 SQL 中的命名占位符匹配。

行工厂

行工厂支持命名列访问,而不仅仅是位置访问。

row_factory.py
import sqlite3

with sqlite3.connect('example.db') as conn:
    # Set row factory for named access
    conn.row_factory = sqlite3.Row
    
    cursor = conn.execute("SELECT * FROM users LIMIT 1")
    row = cursor.fetchone()
    
    # Access columns by name
    print(f"User {row['name']} is {row['age']} years old")

sqlite3.Row 工厂提供基于索引和名称的列访问。

这使得代码对于架构更改(列顺序)更健壮,也更具可读性。

事务

execute 方法参与 SQLite 的自动事务。

transactions.py
import sqlite3

with sqlite3.connect('transactions.db') as conn:
    try:
        conn.execute("CREATE TABLE IF NOT EXISTS accounts (id INTEGER, balance REAL)")
        conn.execute("INSERT INTO accounts VALUES (1, 1000.0)")
        conn.execute("INSERT INTO accounts VALUES (2, 500.0)")
        
        # Transfer money
        conn.execute("UPDATE accounts SET balance = balance - 100 WHERE id = 1")
        conn.execute("UPDATE accounts SET balance = balance + 100 WHERE id = 2")
        
        # Will commit automatically if no exceptions
    except sqlite3.Error as e:
        print("Transaction failed:", e)
        # Automatic rollback occurs on exception

SQLite 会在 DML 语句之前自动启动事务。“with”语句在成功时提交,或在出现异常时回滚。

对于显式控制,请使用 BEGINCOMMITROLLBACK 语句。

自定义函数

SQLite 可以通过 execute 从 SQL 调用 Python 函数。

custom_functions.py
import sqlite3

def calculate_bonus(age):
    return age * 10  # Simple bonus calculation

with sqlite3.connect(':memory:') as conn:
    conn.create_function("bonus", 1, calculate_bonus)
    
    conn.execute("CREATE TABLE employees (name TEXT, age INTEGER)")
    conn.execute("INSERT INTO employees VALUES ('Alice', 30)")
    
    # Use Python function in SQL
    cursor = conn.execute("""
        SELECT name, age, bonus(age) as bonus 
        FROM employees
    """)
    
    for row in cursor:
        print(f"{row['name']}: {row['age']} years, ${row['bonus']} bonus")

这将 Python 函数注册为 SQL 函数。 然后可以从 SQL 语句中调用该函数。

自定义函数使用 Python 逻辑扩展了 SQLite 的功能,同时保持了查询性能。

最佳实践

资料来源

作者

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

列出所有 Python 教程