Python sqlite3更新数据库表时字符串字段更新失败求助
解决SQLite3更新字符串字段的问题
嘿,我来帮你搞定这个SQLite3的更新问题!你遇到的报错 sqlite3.OperationalError: no such column: Adventure 其实原因很明确——字符串类型的值没有被正确包裹在引号里,而且你当前的SQL拼接方式还存在严重的SQL注入风险,咱们一步步来改。
问题根源分析
你现在是直接把用户输入的内容拼接到SQL语句里:
- 当更新数字字段时,比如输入
9.99,拼接后的SQL是SET price=9.99 WHERE game='xxx',数字不需要引号,SQL能正确识别,所以运行正常。 - 但更新字符串时,比如输入
Adventure,拼接后的SQL就变成了SET genre=Adventure WHERE game='xxx',SQL会把Adventure当成一个列名去查找,自然就报错“找不到这个列”了。
而且这种直接拼接用户输入的写法非常危险,万一有人输入恶意内容,会直接篡改你的数据库(也就是SQL注入攻击)。
正确解决方案:使用参数化查询
这是操作数据库的最佳实践,既解决了字符串引号的问题,又能彻底避免SQL注入。修改后的代码如下:
import sqlite3 # 别忘了导入模块哦 def amendRec(): edit = "yes" while edit != 'exit': keyfield = input("enter the game name of the record you want to edit. ") field = input("enter the field you want to change. ") newVal = input("enter the new data for this field. ") # 用?作为值的占位符,参数放在元组里传递给execute # 注意:字段名不能用参数化,建议加个列名白名单校验更安全 try: # 用format处理字段名,值用参数化占位符 cursor.execute( "UPDATE tblGames SET {} = ? WHERE game = ?".format(field), (newVal, keyfield) ) conn.commit() print("\nRecord Updated\n") except sqlite3.OperationalError as e: print(f"Error updating record: {e}\n可能是输入的游戏名或字段名无效哦。") edit = input("type 'exit' to stop editing, or press enter to continue. \n") showtable()
代码要点说明
- 参数化占位符
?:SQLite3会自动处理不同类型值的格式——字符串会自动加上引号,数字保持原样,彻底解决你之前的类型适配问题。 - 字段名处理:字段名不能用参数化,所以如果是用户输入的字段名,最好提前做个白名单校验(比如检查是否在
['game', 'genre', 'price']这类合法列名列表里),防止恶意输入。 - 恢复异常捕获:把try-except加回来,能友好提示用户错误原因,而不是直接崩溃。
额外提示
之前你手动给keyfield加引号的方式也不安全,用参数化查询后就完全不需要自己处理引号了,数据库驱动会帮你做好所有格式适配。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

