奇怪的 SQLAlchemy 错误消息: TypeError: ‘ dict’对象不支持索引

我使用手工制作的 SQL 从 PG 数据库中获取数据,使用的是 SqlAlchemy。我正在尝试一个查询,其中包含 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)并返回结果。变量 con 只是以前建立的到数据库的连接。

75826 次浏览

看来你的问题可能与 这个窃听器有关。

在这种情况下,您应该使用三重逸出作为变通方法。

您必须给 %%以使用它作为 %,因为 python 中的 %用作字符串格式,所以当您编写单个 %时,它假设您将用这个替换某个值。

因此,当你想在字符串中放置单个 %时,请始终放置双 %

SQLAlchemy 有一个用于包装文本的 text()函数,可以正确地转义 SQL。

也就是说。

res = executeSql(sqlalchemy.text(sql))

应该为您工作,并节省您必须做手动逃生。

这也可能是传递给 SQL 的 case-in 参数以 DICT 格式声明,并以 LIST 或 TUPPLE 的形式在 SQL 中进行操作的结果。

当这个错误出现时,我又发现了一个例子:

c.execute("SELECT * FROM t WHERE a = %s")

换句话说,如果在查询中提供参数(%s) ,但是忘记添加查询参数。在这种情况下,错误消息非常具有误导性。

还有一个注意事项-您必须在注释中转义(或删除) %字符。不幸的是,sqlalchemy.text(query_string)在评论中没有跳过百分比符号。

我无法在 sql 炼金术 1.2版本文件中找到“ ExecuteSql”,但下面一行对我很有用

engine.execute(sqlalchemy.text(sql_query))

另一种解决问题的方法是使用正则表达式(如果不想转义 %字符或使用 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 模式不同,正则表达式允许匹配字符串中的任何位置,除非正则表达式显式锚定到字符串的开头或结尾。

对于锚点,可以使用断言 $作为字符串的结尾(或者 ^作为开头)。