Python拼接MySQL更新语句单引号被转义导致执行失败的解决方法
问题核心定位
- 你看到的
query = 'UPDATE \'college_general\' ...'形式,是Python在交互式控制台、调试器中展示字符串对象的默认repr格式,实际字符串的内容里根本没有那些反斜杠转义符。举个例子:定义s = 'it\'s',直接print(s)会输出it's,完全没有多余的反斜杠,只有在控制台直接输入变量名回车、或者调用repr(s)时,才会显示带转义符的形式。只要你不主动把repr()的结果传给数据库驱动,这个显示效果不会影响实际执行,更不是报错的根因。 - 真正触发报错的是你现有代码的几处硬语法bug:
- MySQL语法规则里,表名、列名这类标识符不能用单引号包裹:单引号在MySQL中仅用于标识字符串、日期这类字面量值,用单引号包表名/列名时,MySQL会把它识别为普通字符串值,根本不会当作要操作的表/列,直接触发语法错误。标识符的正确包裹符号是反引号(`)。
- update函数存在参数缺失:WHERE条件里直接引用了未定义的
id变量,既没有把college_id作为入参传入,运行时要么触发NameError,要么错误引用全局作用域的无关变量,定位不到要修改的目标行。 - 直接把变量值硬拼到SQL字符串里:当传入的value、id里包含单引号、反斜杠这类特殊字符时,会直接打断SQL语法,同时存在SQL注入风险。
正确实现方案
完全不需要手动处理字符串的转义效果,按以下逻辑调整即可:
- 动态拼接的表名、列名部分,替换为反引号包裹,同时提前做合法性校验,避免非法值注入。
- 所有要传入的字段值,全部用数据库驱动提供的占位符代替,不要手动把值拼到SQL字符串里,转义工作完全交给驱动处理。
- 给update函数补全college_id参数,不要在函数内部硬引用全局变量。
正确代码示例:
def update(table, column, value, target_college_id): # 动态拼接的标识符提前做白名单校验,避免注入 allowed_identifiers = { "table": ["college_general"], "column": ["fees"] } if table not in allowed_identifiers["table"] or column not in allowed_identifiers["column"]: raise ValueError("传入的表名或列名不在允许范围内") # 标识符用反引号包裹,值的位置用%s占位符,不要手动拼值 sql = f"UPDATE `{table}` SET `{column}` = %s WHERE `college_id` = %s" # 返回SQL模板和参数元组,不要直接返回拼好值的字符串 return sql, (value, target_college_id) # 调用逻辑 fee = 180000 sql, params = update("college_general", "fees", fee, target_college_id=2) # 执行时把参数单独传给execute,驱动会自动完成值的转义 cursor.execute(sql, params)
执行效果说明
上述代码实际传给MySQL的SQL语句为:
UPDATE `college_general` SET `fees` = '180000' WHERE `college_id` = '2'
完全符合MySQL语法规范,既不会出现单引号包标识符的语法错误,也不需要手动处理字符串转义,同时规避了SQL注入风险。
补充说明:如果你之前真的把带转义反斜杠的字符串传到了数据库,大概率是调试时不小心把
repr()的返回值赋值给了执行用的query变量——正常f-string生成的字符串内容是没有多余转义符的,这种情况只要换回正常的字符串变量即可。
内容的提问来源于stack exchange,提问作者Herschelle
相关产品推荐
相关产品推荐

