此问题在此处已有答案:
Passing table name as a parameter in psycopg2(10个答案)
How can I do a line break (line continuation) in Python (split up a long line of source code)?(10个答案)
11天前关闭
我已经定义了一个字典,其中包含几个参数和它们的值,这些参数和值最终将用于构建SQL查询
query_params = collections.OrderedDict(
{'table_name':'publilc.churn_data',
'date_from':'201712',
'date_to':'201805',
'class_target':'NPA'
})
字符串
这些参数将用于以下查询:
sql_data_sample = str("""select * from %s # get value of table_name
where dt = %s #get value of date_from
and target in ('ACTIVE')
----------------------------------------------------
union all
----------------------------------------------------
(select * from %s #get value of table_name
where dt = %s #get value of date_to
and target in (%s));""") #get value of class_target
%("'"+.join(str(list(query_params.values())[0])) + "'" +
"'"+.join(list(query_params.values())[1]) + "'" +
"'"+.join(list(query_params.values())[2]) + "'" +
"'"+.join(list(query_params.values())[3]) + "'" )
型
然而,这给了我一个缩进错误,如下所示:
get_ipython().run_line_magic('("\'"+.join(list(query_params.values())[0])', '+ "\'"')
^
IndentationError: unexpected indent
型
查询最终应该看起来像这样:
select *from public.churn_data
where dt = '201712'
and target in ('ACTIVE')
----------------------------------------------------
union all
----------------------------------------------------
(select * from public.churn_data
where dt = '201805'
and target in ('NPA'));
型
我无法找出错误的来源。是因为table_name中的public.吗?有人能帮我解决这个问题吗?
2条答案
按热度按时间holgip5t1#
请使用文档中描述的参数化查询
既然你已经有了一个dict,你可以这样做:
字符串
我还没有测试过if是否能和有序的dict一起工作,但我认为应该可以。如果不能,你可以在把有序的dict作为参数Map传递之前把它变成一个常规的dict。
EDIT除非你以后需要你的参数是一个OrderedDict,否则使用一个常规的Dict。据我所知,你只选择了一个OrderedDict来保留
list(query_params.values())[0]
的值顺序。EDIT2表名和字段名不能使用绑定传递。Antoine Dusséaux在this answer中指出,自2.7版本以来,psycopg2提供了一种或多或少的安全方式来实现这一点。
型
你可能需要从你的dict中删除
table_name
,我不确定psycopg2对参数dict中的附加项的React,我现在不能测试它。应该指出的是,这仍然会带来SQL注入的风险,除非绝对必要,否则应该避免。通常情况下,表和字段名称是查询字符串中相当固定的一部分。
下面是
sql
模块的相关文档。h7appiyu2#
您可以使用以下代码来删除缩进错误
字符串
但是你需要再传递一个参数,因为你使用了%s 5次,但是参数只有4个