Python3.7用f-string格式化含%的SQL报错如何解决?
报错核心原因
Python 3.7的f-string本身不会将单独的%识别为格式占位符,你遇到的Invalid Python format string for query报错来自两个问题:
- 手动给参数加转义单引号的写法容易触发引号匹配异常,且无法处理参数本身带单引号的场景
- 你使用的SQL执行组件会对传入的SQL字符串做格式校验,将裸拼接语句里的
%误判为老式%字符串格式化的占位符,最终抛出格式无效错误。
正确实现方式
1. 静态SQL文本生成(仅适用于测试场景)
不需要手动给参数转义单引号,直接在f-string内用单引号包裹参数即可,%通配符无需额外转义:
condition1 = "Status for JOB1%" query = f"""SELECT job_id, job_type, job_desc FROM status WHERE status_desc like '{condition1}' and job_type = 1"""
生成的SQL语句和你预期的完全一致,f-string不会对语句内的%做特殊处理。
如果生成的SQL还需要传入支持%格式化的组件做二次处理,只需要把like子句里的通配符%写成%%转义即可,二次格式化后会还原为单个%:
condition1 = "Status for JOB1%%" query = f"""SELECT job_id, job_type, job_desc FROM status WHERE status_desc like '{condition1}' and job_type = 1"""
2. 生产环境推荐写法(参数化查询)
禁止直接用字符串拼接生成生产环境执行的SQL,这种写法存在SQL注入风险,且特殊字符处理极易出错。应该使用数据库驱动自带的参数化查询能力,由驱动自动完成引号包裹、特殊字符转义:
condition1 = "Status for JOB1%" # SQL语句里用驱动支持的占位符,不要拼接参数 # pymysql、psycopg2等驱动用%s作占位符,sqlite3用?作占位符 query = """SELECT job_id, job_type, job_desc FROM status WHERE status_desc like %s and job_type = %s""" # 执行时将参数以元组形式单独传入,驱动会自动处理所有格式问题 cursor.execute(query, (condition1, 1))
这种写法下,%只会被识别为LIKE的通配符,不会触发格式校验报错,同时从根源上避免SQL注入风险。
内容的提问来源于stack exchange,提问作者May Aung
相关产品推荐
相关产品推荐

