
SQLite 的 UPDATE 操作在 Python 中执行后不会自动保存,必须显式调用 conn.commit() 提交事务,否则更改将被丢弃;同时原始代码存在 SQL 注入风险和资源未正确释放问题。
sqlite 的 update 操作在 python 中执行后不会自动保存,必须显式调用 `conn.commit()` 提交事务,否则更改将被丢弃;同时原始代码存在 sql 注入风险和资源未正确释放问题。
在使用 sqlite3 模块执行数据更新时,一个常见误区是认为 cursor.execute() 调用后修改即刻持久化——实际上,SQLite 默认以事务(transaction)方式运行,所有 DML 操作(如 INSERT、UPDATE、DELETE)都处于待提交状态,必须显式调用 conn.commit() 才能将变更写入数据库文件。
此外,原代码还存在以下关键问题:
- ? SQL 注入漏洞:直接拼接字符串构造 SQL 查询(f"UPDATE ... = {new_name}"),若 old_name 或 new_name 包含单引号或恶意语句(如 ' OR 1=1 --),将导致严重安全风险;
- ? 连接未正确关闭:conn.close() 位于 else 分支之后,属于不可达代码(unreachable),无论成功或失败均不会执行,易引发连接泄漏;
- ? 异常处理粒度粗:捕获 Exception 过于宽泛,不利于定位具体错误类型(如 sqlite3.OperationalError 或 sqlite3.IntegrityError)。
✅ 正确做法如下(推荐使用参数化查询 + 上下文管理器):
import sqlite3
import os
def update(self, old_name, new_name):
db_path = os.path.join(self._path, "files.db")
try:
# 使用上下文管理器自动管理连接生命周期
with sqlite3.connect(db_path) as conn:
cursor = conn.cursor()
# ✅ 安全:使用 ? 占位符进行参数化查询
query = "UPDATE files SET filename = ? WHERE filename = ?"
cursor.execute(query, (new_name, old_name))
# ✅ 必须调用 commit() —— 在 with 块内会自动提交(若无异常)
# conn.commit() # 实际上 with 自动 commit,但显式写出更清晰
return True
except sqlite3.Error as e:
# 捕获具体 SQLite 异常,便于调试
print(f"Database error: {e}")
return False
# ✅ 自动关闭连接:with 语句确保 conn.close() 总是被执行
? 关键要点总结:
- commit() 是持久化更新的必要步骤,不可省略;
- 始终使用参数化查询(? 占位符 + 元组参数),杜绝 SQL 注入;
- 优先采用 with sqlite3.connect(...) as conn: 确保连接安全释放;
- 避免裸 except Exception,应捕获更具体的异常类型;
- 若需判断是否影响行数,可检查 cursor.rowcount(执行后返回受影响行数,-1 表示未知)。
遵循以上实践,即可安全、可靠地完成 SQLite 数据库字段更新操作。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











