TypeError: 'dict' object does not support indexing thrown on second instance of this query
TypeError: 'dict' object does not support indexing thrown on second instance of this query
所以我正在使用以下代码基于 Flask 中的用户输入构建查询:
if empty_indic_form.validate_on_submit():
query='select name, year, value, display_name from literal inner join ent on ent_id=ent.id where display_name in ('
for i in indic_form.indicators.data:
query=query+'\''+i+'\','
query=query[:-1]+') '
query=query+'and name in ('
for c in order_c:
query=query+c+','
query=query[:-1]+')'
data_return=db.engine.execute(query).fetchall()
我已经确认查询看起来像它应该的那样,甚至有一个早期的会话,它返回了我期望的 rowproxy 对象列表。但是现在无论我做什么我都会收到这个错误!
我已将查询设置为模板中的一个变量,以便打印出来,这是我得到的结果:
select name, year, value, display_name from literal
inner join ent
on ent_id=ent.id
where display_name in ('Energy savings of primary energy (TJ)','Adolescent birth rate (women aged 15-19 years)','Net migration rate','Transmission and distribution losses (%)')
and name in ('Burkina Faso', 'Ghana', 'Saudi Arabia', 'Pakistan')
我 运行 直接在我的 Postgres 数据库上,结果是 g运行d.
在错误转储中,我注意到 data_return=db.engine.execute(query).fetchall()
行是使用一个空字典作为参数构建的,这当然会在最后抛出该错误。我可以强制它不这样做吗?查询对象看起来像上面那样,现在有什么问题吗?我是否应该在刷新页面或转到主页时终止数据库会话?
您方法中的根本错误是使用字符串连接来构建 SQL 查询。如果 indic_form.indicators.data
或 order_c
是用户提供的数据,例如来自 HTTP 请求的数据,您可能已经为 SQL injection 打开了自己的大门。错误
TypeError: 'dict' object does not support indexing
是这种串联的结果:您的查询字符串包含流氓 "%"
,它是 psycopg 占位符语法的一部分 – 通常与 SQLAlchemy 与 Postgresql 对话。这正是不应进行手动连接的原因。正确逃脱可能很难。
使用 tuples adaptation in Psycopg2. In SQLAlchemy you'd use the in_
column operator, or an expanding bind param that were introduced in version 1.2.
将值列表传递给 IN
运算符
不幸的是,在您的特定情况下,SQLAlchemy 包装引擎有一个陷阱:由于您的所有参数都是元组,SQLAlchemy 引擎认为您正在尝试通过它是一个可迭代的参数元组作为 multiparams and uses executemany()
automatically. You can work around this by using the text()
构造,它允许 DB-API 不可知的绑定参数语法和字典作为参数容器:
from sqlalchemy import text
...
if empty_indic_form.validate_on_submit():
# Note that the placeholders shouldn't have enclosing parentheses
query = """SELECT name, year, value, display_name
FROM literal
INNER JOIN ent ON ent_id = ent.id
WHERE display_name IN :display_name
AND name IN :name"""
data_return = db.engine.execute(
text(query), {'display_name': tuple(indic_form.indicators.data),
'name': tuple(order_c)}).fetchall()
回顾一下:永远不要使用字符串连接或手动格式化来构建 SQL 查询。始终使用占位符/绑定参数。
所以我正在使用以下代码基于 Flask 中的用户输入构建查询:
if empty_indic_form.validate_on_submit():
query='select name, year, value, display_name from literal inner join ent on ent_id=ent.id where display_name in ('
for i in indic_form.indicators.data:
query=query+'\''+i+'\','
query=query[:-1]+') '
query=query+'and name in ('
for c in order_c:
query=query+c+','
query=query[:-1]+')'
data_return=db.engine.execute(query).fetchall()
我已经确认查询看起来像它应该的那样,甚至有一个早期的会话,它返回了我期望的 rowproxy 对象列表。但是现在无论我做什么我都会收到这个错误!
我已将查询设置为模板中的一个变量,以便打印出来,这是我得到的结果:
select name, year, value, display_name from literal inner join ent on ent_id=ent.id where display_name in ('Energy savings of primary energy (TJ)','Adolescent birth rate (women aged 15-19 years)','Net migration rate','Transmission and distribution losses (%)') and name in ('Burkina Faso', 'Ghana', 'Saudi Arabia', 'Pakistan')
我 运行 直接在我的 Postgres 数据库上,结果是 g运行d.
在错误转储中,我注意到 data_return=db.engine.execute(query).fetchall()
行是使用一个空字典作为参数构建的,这当然会在最后抛出该错误。我可以强制它不这样做吗?查询对象看起来像上面那样,现在有什么问题吗?我是否应该在刷新页面或转到主页时终止数据库会话?
您方法中的根本错误是使用字符串连接来构建 SQL 查询。如果 indic_form.indicators.data
或 order_c
是用户提供的数据,例如来自 HTTP 请求的数据,您可能已经为 SQL injection 打开了自己的大门。错误
TypeError: 'dict' object does not support indexing
是这种串联的结果:您的查询字符串包含流氓 "%"
,它是 psycopg 占位符语法的一部分 – 通常与 SQLAlchemy 与 Postgresql 对话。这正是不应进行手动连接的原因。正确逃脱可能很难。
使用 tuples adaptation in Psycopg2. In SQLAlchemy you'd use the in_
column operator, or an expanding bind param that were introduced in version 1.2.
IN
运算符
不幸的是,在您的特定情况下,SQLAlchemy 包装引擎有一个陷阱:由于您的所有参数都是元组,SQLAlchemy 引擎认为您正在尝试通过它是一个可迭代的参数元组作为 multiparams and uses executemany()
automatically. You can work around this by using the text()
构造,它允许 DB-API 不可知的绑定参数语法和字典作为参数容器:
from sqlalchemy import text
...
if empty_indic_form.validate_on_submit():
# Note that the placeholders shouldn't have enclosing parentheses
query = """SELECT name, year, value, display_name
FROM literal
INNER JOIN ent ON ent_id = ent.id
WHERE display_name IN :display_name
AND name IN :name"""
data_return = db.engine.execute(
text(query), {'display_name': tuple(indic_form.indicators.data),
'name': tuple(order_c)}).fetchall()
回顾一下:永远不要使用字符串连接或手动格式化来构建 SQL 查询。始终使用占位符/绑定参数。