Python3.7操作SQLite3更新删除表记录报错问题求助
报错根因
两个报错的核心原因完全一致:cursor.fetchall()返回的每一行数据都是元组格式,你打印看到的('Joe Blow 12345',)就是单元素元组,你直接把这个元组传给SQL语句做参数,才触发了两类错误:
- 参数化查询报类型错误,是因为NAME字段需要字符串类型值,你传入的是元组,类型不匹配
- f字符串拼接报语法错误,是因为元组转字符串后自带括号、逗号,拼出来的SQL实际为
WHERE NAME = ('Joe Blow 12345',),语法不符合SQLite规范,所以在右括号位置抛错。
另外你贴的代码里还有两处低级错误:一是参数化查询的execute()前漏写了cursor.前缀;二是执行完增删改操作后没有调用commit()提交事务,就算语句执行成功,修改也不会持久化到数据库。
修正后可直接运行的代码
优先用参数化查询实现,不要用字符串拼接SQL,既容易出语法错,还存在SQL注入风险。
方案1:更新USED字段标记已抽取
import sqlite3 import secrets # 对应你使用的安全随机模块 # 替换为你自己的数据库文件路径 conn = sqlite3.connect('your_biz_db.db') cursor = conn.cursor() # 直接在SQL层过滤ROLE为FLM、且未被抽取过的记录,不需要拉取全表数据 cursor.execute("SELECT NAME FROM everyone WHERE ROLE = 'FLM' AND COALESCE(USED, '') != 'Y'") valid_names = cursor.fetchall() pick_total = 3 used_mark = "Y" for _ in range(pick_total): # 取元组第0位,才是真正的姓名字符串 selected_name = secrets.choice(valid_names)[0] print(f"已抽取:{selected_name}") try: cursor.execute( """UPDATE everyone SET USED = ? WHERE NAME = ?""", (used_mark, selected_name) ) except Exception as e: print(f"数据库更新失败:{str(e)}") break # 必须提交事务,否则所有修改不会生效 conn.commit() # 释放资源 cursor.close() conn.close()
方案2:直接删除已抽取的记录
如果不需要保留已抽取人员记录,只需要把上面代码里的UPDATE语句替换为DELETE语句即可:
cursor.execute( """DELETE FROM everyone WHERE NAME = ?""", (selected_name,) )
优化建议
- 如果需要避免重复抽取到同一个人,可以在每次抽取后把对应名字从
valid_names列表里移除,防止小概率重复选中 - 所有数据库增删改操作都要记得加异常捕获,操作完成后必须提交事务,否则修改会在连接关闭后自动回滚
- 尽量不要用字符串拼接的方式写SQL,参数化查询是更安全、更不容易出语法问题的写法
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

