奇怪的 SQLAlchemy 错误消息:TypeError: 'dict' object does not support indexing

Posted

技术标签:

【中文标题】奇怪的 SQLAlchemy 错误消息:TypeError: \'dict\' object does not support indexing【英文标题】:Strange SQLAlchemy error message: TypeError: 'dict' object does not support indexing奇怪的 SQLAlchemy 错误消息:TypeError: 'dict' object does not support indexing 【发布时间】:2012-01-29 06:14:59 【问题描述】:

我正在使用手工制作的 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) 并返回结果。变量 conn 只是先前建立的与数据库的连接。

【问题讨论】:

可以发executeSql(...)的代码吗?还有,SELECT 语句中真的有RETURNING * 吗? @van 我错过了那个。导致问题的 SQL 中没有“返回 *”。我会更正这个问题。 这个答案 [***.com/questions/3944276/… 有帮助吗? @van:谢谢!是的,它确实。我不得不使用'\%%' 而不是'%'。该语句现在已正确执行。 太棒了。为了完整起见,请发布一个对您有用的简短答案(并接受它)。 【参考方案1】:

您必须提供%% 才能将其用作%,因为python 中的% 用作字符串格式,因此当您编写单个% 时,它假定您将用它替换一些值。

因此,当您想将单个 % 放置在带有查询的字符串中时,始终放置双 %

【讨论】:

我希望他们能更新那个错误信息,每次我得到它我最终都会登陆这个页面并回答【参考方案2】:

SQLAlchemy 有一个 text() 函数用于包装文本,这似乎可以为您正确转义 SQL。

res = executeSql(sqlalchemy.text(sql))

应该为你工作,让你不必手动转义。

【讨论】:

这应该是选择的答案。它解决了我的问题。 请注意,这并不能逃脱 cmets,否则是一个绝妙的解决方案。 这对我有用,并且比使用 double % 更改所有查询更容易实现【参考方案3】:

我在 sqlalchemy version 1.2 docs 中找不到“executeSql”,但下面的行对我有用

engine.execute(sqlalchemy.text(sql_query))

【讨论】:

【参考方案4】:

您的问题似乎与this bug有关。

在这种情况下,您应该使用三次转义作为解决方法。

【讨论】:

【参考方案5】:

当此错误出现时,我发现了另外一种情况:

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

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

【讨论】:

【参考方案6】:

还有一点需要注意 - 您还必须在 cmets 中转义(或删除)% 字符。不幸的是,sqlalchemy.text(query_string) 没有逃脱 cmets 中的百分号。

【讨论】:

【参考方案7】:

如果您不想转义 % 字符或使用 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 和正则表达式都包含在 documentation on pattern matching 中。

注意:

与 LIKE 模式不同,正则表达式可以匹配字符串中的任何位置,除非正则表达式明确锚定到字符串的开头或结尾。

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

【讨论】:

【参考方案8】:

这也可能是由这种情况导致的——如果要传递到 SQL 的参数以 DICT 格式声明并且在 SQL 中以 LIST 或 TUPPLE 的形式进行操作。

【讨论】:

以上是关于奇怪的 SQLAlchemy 错误消息:TypeError: 'dict' object does not support indexing的主要内容,如果未能解决你的问题,请参考以下文章

SQLAlchemy随机错误

如何返回 Flask-SqlAlchemy 错误详细信息

sqlalchemy 1.1.10 oracle连接错误

多线程scoped_session中的SQLAlchemy

尝试使用 SQLAlchemy 捕获完整性错误

Redshift:DateDiff 调用上的 SqlAlchemy 错误