使用SQLAlchemy执行带rf前缀f字符串的SQL时报unsupported format character错误
报错根因
- 该报错和MySQL连接权限、SQL语法错误没有关联,本质是PyMySQL驱动的字符串解析规则和你写的SQL内容冲突导致的。
- 报错提示中
unsupported format character 'C' at index 41的定位完全对应你写的SQL语句:从SQL开头逐字符计数,'%CT%'里的第一个百分号刚好落在索引41的位置,它后面紧跟的字符就是大写的C。 - PyMySQL在处理传入的SQL字符串时,会默认把所有
%符号识别为参数格式化占位符的起始标记,要求后续紧跟合法的格式说明符;%C不符合格式规则,就会直接抛出校验错误。 - 你给字符串加的
rf前缀无法规避这个问题:r原始字符串前缀只在Python语法解析阶段生效,用来处理反斜杠类转义;驱动拿到SQL字符串后的解析逻辑完全独立,不会受Python层面的字符串前缀影响。
可落地的解决方案
- 直接对SQL中的百分号做转义
按照PyMySQL的解析规则,要让驱动把%识别为普通文本而非占位符,需要将单个%双写为%%,此时不需要额外给字符串加rf前缀。
修改后的核心代码:cst_delete_query = """delete from customer where STATUS like '%%CT%%'""" - 采用参数绑定的规范写法
硬编码拼接SQL不仅容易触发当前的占位符冲突,还存在SQL注入风险,推荐用SQLAlchemy内置的文本表达式实现参数绑定,从根源上避免字符串解析问题。
示例代码:from sqlalchemy import text # SQL文本中使用命名占位符,不直接写入带%的匹配逻辑 cst_delete_query = text("delete from customer where STATUS like :match_str") with engine.connect().execution_options(autocommit=True) as conn: # 把包含%的匹配规则作为参数值传入,驱动会将%识别为参数内容的一部分 conn.execute(cst_delete_query, {"match_str": "%CT%"}) - 临时兼容方案
如果暂时不想改动原有SQL逻辑,也可以调整执行选项关闭SQLAlchemy的参数自动解析机制,跳过对SQL字符串中%的校验,但这种写法长期维护性差,不推荐在生产环境使用。
内容的提问来源于stack exchange,提问作者S S
相关产品推荐
相关产品推荐

