Python中的“ValueError:不支持的格式字符'”(0x22)at ...“

时间:2013-08-01 19:16:19

标签: python regex string list

我见过几个类似的线程,但试图逃避字符并不适合我。

简而言之,我有一个字符串列表,我正在迭代,这样我的目标是构建一个查询,将列表中的许多字符串合并到一个'Select,Like'查询中。

这是我的代码(Python)

def myfunc(self, cursor, var_list):
   query = "Select var FROM tble_tble WHERE"
   substring = []
   length = len(var_list)
   iter = length

   for var in var_list:
      if (iter != length):
         substring.append(" OR tble_tble.var LIKE %'%s'%" % var)
      else:
         substring.append(" tble_tble.var LIKE %'%s'%" % var)
      iter = iter - 1

   for str in substring:
      query = query + str
...

那应该够了。如果从我之前声明的声明中显而易见,我正在尝试 构建一个查询,该查询在列表中运行SQL“LIKE” 比较相关字符串。

感谢您的时间,并随时提出任何问题以便澄清。

3 个答案:

答案 0 :(得分:7)

首先,您的问题与SQL无关。扔掉所有与SQL相关的代码并执行此操作:

var = 'foo'
" OR tble_tble.var LIKE %'%s'%" % var

你会得到同样的错误。这是因为您正在尝试% - 使用带有迷路%标志的字符串进行格式化。因此,它试图弄清楚如何处理%'并失败。


你可以逃避这些迷路%这样的迹象:

" OR tble_tble.var LIKE %%'%s'%%" % var

然而,这可能不是你想要做的。


首先,考虑使用{} - 格式化而不是% - 格式化,尤其是当您尝试构建格式化的字符串,其中包含%个字符他们。它避免了逃避它们的需要。所以:

" OR tble_tble.var LIKE %'{}'%".format(var)

但是,更重要的是,你根本不应该做这种格式化。不要将值格式化为SQL字符串,只需将它们作为SQL参数传递。如果您使用的是sqlite3,请使用?参数标记;对于MySQL,%s;对于不同的数据库,请阅读其文档。所以:

" OR tble_tble.var LIKE %'?'%"

这里没有什么可以出错,也没有什么需要逃脱的。当您使用查询字符串调用execute时,请将[var]作为参数传递。

这更简单,通常更快,并且巧妙地避免了处理边缘情况的大量愚蠢错误,最重要的是,它可以防止SQL注入攻击。

sqlite3 docs更详细地解释了这一点:

  

通常,您的SQL操作需要使用Python变量中的值。您不应该使用Python的字符串操作来汇编查询...而是使用DB-API的参数替换。将?作为占位符放在要使用值的位置,然后提供值元组作为游标execute()方法的第二个参数。 (其他数据库模块可能使用不同的占位符,例如%s或:1。)...


最后,正如其他人在评论中指出的那样,在LIKE条件下,您必须将百分号置于引号内,而不是外部。所以,无论你采用哪种方式解决这个问题,你都会遇到另一个问题需要解决。但那个应该容易多了。 (如果没有,你可以随时回来问另一个问题。)

答案 1 :(得分:0)

您需要像这样转义%,您需要更改引号以包含%生成正确的SQL

" OR tble_tble.var LIKE '%%%s%%'"

例如:

var = "abc"
print " OR tble_tble.var LIKE '%%%s%%'" % var

它将被翻译为:

OR tble_tble.var LIKE '%abc%'

答案 2 :(得分:0)

这是一个古老的问题,因此,为了与上述所有软件的最新版本配合使用,我要做的事情是

citp = "SomeText" + "%%"  # if your LIKE wants database rows that match start text, else ... 
citp = "%%" + "SomeQueryText" + "%%"   

        chek_copies = 'SELECT id, code, null as num from indicator WHERE code LIKE "%s" AND owner = 1 ;'
        check_copies = (chek_copies % (citp))
        copies_checked = pd.read_sql(check_copies, con=engine)

像魅力一样工作-但是反复无常