【问题标题】:python sqlite3 unrecognized token: "{"python sqlite3无法识别的令牌:“{”
【发布时间】:2026-01-05 11:45:02
【问题描述】:

这个语法:

consulta.execute("SELECT * FROM {0} WHERE rut LIKE '%"+str(cadena)+"%'".format(tablepx))

产生错误:

sqlite3.OperationalError: unrecognized token: "{"

我也试过这个:

consulta.execute("SELECT * FROM {0} WHERE rut LIKE ?".format(tablepx),(cadena,))

它不发送错误但什么也没发生,它不起作用,因为我从数据库中得到零结果。

我不知道如何使用'%" + str(cadena) +"%',我总是使用.format()

【问题讨论】:

  • str(cadena) 长什么样子?
  • 啊,关于连接 SQL 查询的日常问题。 不要。使用参数化查询。

标签: python python-3.x sqlite


【解决方案1】:

您正在格式化字符串的最后一部分:

"%'".format(tablepx)

在将其连接到"..." + str(cadena) 的结果之前。因此,first 字符串文字中的{0} 占位符未填充,您将留下"SELECT * FROM {0} WHERE rut LIKE '%...%'" 作为查询(... 替换为cadena 的值)。

您可以通过将 .format() 调用移动到 "SELECT * FROM {0} WHERE rut LIKE '%" 字符串文字来解决此问题。或者通过使用第二个占位符 {1} 来显示 cadeda 值的位置,而不是使用 + 连接。

然而,您不应该首先使用字符串连接将cadena 放入字符串中。通过使用 ? 占位符和查询参数值,您的想法是正确的,但是您忘记将 % LIKE 查询字符添加到您的 cadena 值。

只需将% 字符添加到cadena 的开头和结尾,然后将其结果用作您的参数:

like_string = '%{0}%'.format(cadena)
consulta.execute(
    "SELECT * FROM {0} WHERE rut LIKE ?".format(tablepx),
    (like_string,))

查询字符串中的? 占位符将用于放置正确转义的LIKE 查询字符串,并在cadena 值的开头和结尾添加%

我怎么强调都不过分,使用str.format() 将表名插入到查询字符串中(就像使用tablepx 一样)会使您面临SQL 注入问题。请参阅this other answer of mine 以获取有关此方面的更多建议以及替代方案。为了安全起见,我至少使用"{0}" 作为表名位置和tablepx.replace('"', '""'),这样SQLite 至少知道在字符串的那部分只接受有效的对象名称:

like_string = '%{0}%'.format(cadena)
consulta.execute(
    'SELECT * FROM "{0}" WHERE rut LIKE ?'.format(tablepx.replace('"', '""')),
    (like_string,))

【讨论】:

  • 谢谢大家,我把这个咨询/跨度>
  • @Giova:但是,我真的不会使用那种格式,因为任何可以设置 cadena 值的不受信任的一方都可以破解您的数据库。
  • 我能做些什么来避免黑客攻击?
  • @Giova:使用我答案末尾的语法。如果tablepx 不是用户提供的东西(或不能提供部分价值),那么我回答中的第一个例子就足够了。两者都通过首先将% 添加到cadena 的开头和结尾来创建like_string,然后使用like_string 作为查询的参数。