问题:奇怪的SQLAlchemy错误消息:TypeError:’dict’对象不支持索引
我正在使用手工SQL,使用SqlAlchemy从PG数据库中获取数据。我正在尝试一个查询,其中包含类似运算符’%’的SQL,并且该查询似乎通过循环抛出SqlAlcjhemy:
sql = """
SELECT DISTINCT u.name from user u
INNER JOIN city c ON u.city_id = c.id
WHERE c.designation=upper('fantasy')
AND c.id IN (select id from ref_geog where short_name LIKE '%opt')
"""
# The last line in the above statement throws the error mentioned in the title.
# However if the last line is change to:
# AND c.id IN (select id from ref_geog where short_name = 'helloopt')
# the script runs correctly.
#
# I also tried double escaping the '%' i.e. using '%%' instead - that generated the same error as previously.
connectDb()
res = executeSql(sql)
print res
closeDbConnection()
谁知道是什么原因导致了这种误导性错误消息,以及我该如何解决?
[[编辑]]
在任何人问之前,上面所包含的功能没有什么特别或特别的地方。例如,函数executeSql()仅调用conn.execute(sql)并返回结果。变量conn只是先前建立的与数据库的连接。
回答 0
您必须%%
使用它,%
因为%
在python中它被用作字符串格式,因此当您编写单个时,%
它会假定您将用此值替换某些值。
因此,当您要%
在查询中始终将string放置为all时,请放置double %
。
回答 1
SQLAlchemy具有text()
包装文本的功能,该文本似乎可以为您正确地转义SQL。
即
res = executeSql(sqlalchemy.text(sql))
应该可以为您工作,并使您不必进行手动转义。
回答 2
我在sqlalchemy 1.2版文档中找不到“ executeSql” ,但以下代码对我有用
engine.execute(sqlalchemy.text(sql_query))
回答 3
看来您的问题可能与此bug有关。
在这种情况下,您应该使用三倍转义来解决。
回答 4
当出现此错误时,我发现了另一种情况:
c.execute("SELECT * FROM t WHERE a = %s")
换句话说,如果您%s
在查询中提供参数(),但您忘记添加查询参数。在这种情况下,错误消息非常容易引起误解。
回答 5
还有一个注意事项-您还必须转义(或删除)%
注释中的字符。不幸的是,sqlalchemy.text(query_string)
不能逃脱评论中的百分号。
回答 6
如果您不想转义%
字符或使用sqlalchemy.text()
,则解决问题的另一种方法是使用正则表达式。
代替:
select id from ref_geog where short_name LIKE '%opt'
尝试(区分大小写的匹配):
select id from ref_geog where short_name ~ 'opt$'
或(不区分大小写):
select id from ref_geog where short_name ~* 'opt$'
两个LIKE
和正则表达式被覆盖中模式匹配的文档。
注意:
与LIKE模式不同,除非将正则表达式明确地锚定到字符串的开头或结尾,否则允许在字符串中的任何位置匹配正则表达式。
对于锚,可以将断言$
用于字符串的结尾(或^
开头)。
回答 7
这也可能是由于这种情况-如果要在DICT formate中声明要传递到SQL的参数,并在SQL中以LIST或TUPPLE的形式对其进行操作。