Python中ValueError: unsupported format character ']'(0x5d)问题求助——未找到%符号却触发错误
解决Python数据库游标执行SQL时的ValueError: unsupported format character ']'问题
这个问题其实很容易被忽略——虽然你代码里没直接写Python的字符串格式化%操作,但你的SQL语句里的[Utilisation %]里的%符号,被数据库驱动的参数绑定机制当成了格式化占位符来解析了!
很多数据库驱动(比如pyodbc)在处理带参数的SQL时,会默认扫描语句中的%符号,把它当作参数占位符的一部分(比如%s)。当它遇到单独的%后面跟着]时,就会误以为这是一个格式字符(比如%d、%s这种),但]并不是合法的格式字符,所以就抛出了这个错误。
解决方法有两种,选一种适合你的就行:
- 转义SQL中的%符号:把SQL里的单个
%改成两个%%,这样驱动就会把它当成普通的百分号处理,而不是格式化占位符:
with conn.cursor() as cur: cur.execute(f""" SELECT FirstName, Surname, FORMAT(TotalHours / NULLIF((ContractHours - RemissionHours), 0) * 100, 'N2') AS [Utilisation %%] FROM t JOIN Staff ON Staff.SID = t.SID WHERE (@IncludeLeavers = 'Yes' OR @IncludeLeavers= 'No' AND Staff.IsCurrent = 1) """, params={ "IncludeLeavers": REPORT_OPTIONS["IncludeLeavers"][0] })
- 避免在SQL别名中使用%符号:直接把别名改成不带百分号的名称,比如
UtilisationPercentage,之后在业务代码里再显示成带%的样式:
with conn.cursor() as cur: cur.execute(f""" SELECT FirstName, Surname, FORMAT(TotalHours / NULLIF((ContractHours - RemissionHours), 0) * 100, 'N2') AS UtilisationPercentage FROM t JOIN Staff ON Staff.SID = t.SID WHERE (@IncludeLeavers = 'Yes' OR @IncludeLeavers= 'No' AND Staff.IsCurrent = 1) """, params={ "IncludeLeavers": REPORT_OPTIONS["IncludeLeavers"][0] }) # 之后获取结果时,再把字段名显示成"Utilisation %"
为什么报错行指向参数那一行?
这是因为驱动是在解析整个SQL语句和参数绑定的时候触发的错误,Python的错误栈会指向execute方法的参数部分,但实际问题出在SQL语句里的%符号上,很容易误导排查方向。
内容的提问来源于stack exchange,提问作者Zedverse
相关产品推荐
相关产品推荐

