使用psycopg2占位符时遇IndexError错误的解决方法
问题描述
我编写了如下代码:
query = "SELECT * FROM appointments WHERE service IN %s AND location LIKE '%London%'" values = (services,) # services是字符串元组 cur.execute(query, values)
执行代码时出现以下错误:
--> cur.execute(query, values) IndexError: tuple index out of range
排查后我认为查询语句中的%L被psycopg2识别为占位符,但values元组中没有对应数据。尝试用%%转义%符号,修改后的查询语句如下:
query = "SELECT * FROM appointments WHERE service IN %s AND location LIKE '%%London%'"
但问题仍未解决,请问该如何修复此问题以实现预期功能?
修复方案
问题的核心不是%L的转义,而是psycopg2对IN子句的元组参数处理逻辑,以及LIKE子句的参数化写法错误。正确处理方式如下:
- 优先使用全参数化写法(推荐)
不要在SQL字符串中硬编码带通配符的匹配串,而是把'%London%'作为第二个参数传入,让psycopg2自动处理所有占位符和转义,彻底避免混淆问题。同时psycopg2会自动将元组参数展开为IN子句需要的格式:
query = "SELECT * FROM appointments WHERE service IN %s AND location LIKE %s" values = (services, '%London%') cur.execute(query, values)
- 若坚持在SQL中写通配符
需要把%London%中的两个%都用%%转义,因为原代码仅转义了前面的%,后面的%仍会被识别为占位符,导致参数数量不匹配:
query = "SELECT * FROM appointments WHERE service IN %s AND location LIKE '%%London%%'" values = (services,) cur.execute(query, values)
之前的修改无效,是因为只转义了London前的%,末尾的%依然被psycopg2当作占位符,而values元组只有一个参数,因此触发IndexError。
内容的提问来源于stack exchange,提问作者zoltan
相关产品推荐
相关产品推荐

