SQLite 在 Python 中执行 UPDATE 语句后,若不显式调用 conn.commit(),更改将仅停留在事务缓存中,不会写入数据库文件,导致“看似执行成功却无实际更新”。
sqlite 在 python 中执行 update 语句后,若不显式调用 `conn.commit()`,更改将仅停留在事务缓存中,不会写入数据库文件,导致“看似执行成功却无实际更新”。
在使用 sqlite3 模块进行数据库更新操作时,事务提交(commit)是必不可少的关键步骤。SQLite 默认启用隐式事务,所有 DML 操作(如 INSERT、UPDATE、DELETE)均在事务中执行,但 Python 的 sqlite3 连接对象不会自动提交——必须手动调用 conn.commit(),否则修改将被回滚(程序结束或连接关闭时自动 rollback)。
此外,原代码中还存在两个严重隐患,需一并修正:
✅ 必须添加 conn.commit()
在 cursor.execute(query) 后立即调用 conn.commit(),确保变更持久化到磁盘:
cursor.execute(query) conn.commit() # ← 关键:提交事务
⚠️ 严禁字符串拼接 SQL(防止 SQL 注入)
原始代码使用 f-string 直接拼接 old_name 和 new_name,极易引发 SQL 注入漏洞(例如 old_name = "'; DROP TABLE files; --")。正确做法是使用参数化查询(? 占位符):
query = "UPDATE files SET filename = ? WHERE filename = ?" cursor.execute(query, (new_name, old_name)) # 参数按顺序传入元组
? conn.close() 永远不会执行
原代码中 conn.close() 写在 else 或 except 分支之后,属于不可达代码(unreachable),会导致连接泄漏。应使用 finally 块或更推荐的上下文管理器(with 语句)确保连接安全关闭。
✅ 推荐重构后的健壮版本:
def update(self, old_name, new_name):
db_path = os.path.join(self._path, "files.db")
try:
with sqlite3.connect(db_path) as conn: # 自动 commit(若无异常)+ 自动 close
cursor = conn.cursor()
cursor.execute(
"UPDATE files SET filename = ? WHERE filename = ?",
(new_name, old_name)
)
# conn.commit() 由 with 语句隐式处理(成功时自动提交)
return True
except sqlite3.Error as e:
print(f"数据库更新失败: {e}")
return False
? 提示:with sqlite3.connect(...) 会自动在退出时提交(无异常)或回滚(发生异常),并关闭连接,是 Python 操作 SQLite 的最佳实践。
总结:SQLite 更新失效的主因是缺失 commit();次要但同等重要的是避免字符串拼接、善用参数化查询,并通过上下文管理器保障资源安全释放。三者缺一不可,方能写出可靠、安全、符合生产标准的数据库操作代码。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











