使用字典来传递参数在Python PostgreSQL的声明(Using a dictionary

2019-10-28 20:18发布

我定义它包含几个参数,并最终将被用来建立一个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'));

我不能够找出其中的错误的来源is.Is因公吧。 table_name中? 是否有人可以帮助我?

Answer 1:

请使用参数化查询中所描述的文档

既然你已经有一个快译通,你可以这样做:

sql_data_sample = """select * from %(table_name)s
           where dt = %(date_from)s
           and target in ('ACTIVE')
           ----------------------------------------------------
           union all
           ----------------------------------------------------
           (select * from %(table_name)s
           where dt = %(date_to)s
           and target in (%(class_target)s));"""

cur.execute(sql_data_sample, query_params)

如果要是有odered字典的作品,但我认为它应该我没有测试过。 如果没有,你可以将它作为参数映射之前让你下令字典常规字典。

编辑除非您需要的参数是一个OrderedDict以后,使用常规的字典。 据我所看到的,你只是选择了一个OrderedDict保存价值秩序的list(query_params.values())[0]

EDIT2表名和字段名不能使用绑定进行传递。 安托万Dusséaux中指出, 这个答案是psycopg2提供或多或少的安全的方式来做到这一点,因为2.7版本。

from psycopg2 import sql

sql_data_sample = """select * from {0}
           where dt = %(date_from)s
           and target in ('ACTIVE')
           ----------------------------------------------------
           union all
           ----------------------------------------------------
           (select * from {0}
           where dt = %(date_to)s
           and target in (%(class_target)s));"""

cur.execute(sql.SQL(sql_data_sample)
                .format(sql.Identifier(query_params['table_name'])), 
            query_params)

您可能需要删除该table_name从你的字典,我不知道在的参数的其他项目psycopg2如何做出反应和快译通现在我无法测试它。

应当指出,这仍对SQL注入的风险,应该尽量避免,除非绝对必要的。 通常情况下,表和字段名称是查询字符串的,而固定部分。

下面是相关的文档sql模块 。



Answer 2:

您可以使用下面的代码删除缩进错误

sql_data_sample = str("""
select * from %s
where dt = %s
and target in ('ACTIVE')
----------------------------------------------------
union all
----------------------------------------------------
(select * from %s
where dt = %s
and target in (%s));""" %(
    "'" + str(list(query_params.values())[0]) + "'" +
    "'" + list(query_params.values())[1] + "'" +
    "'" + list(query_params.values())[2] + "'" +
    "'" + list(query_params.values())[3] + "'"
))

但是,你需要通过你使用%s的5倍,但PARAMS只有4个多一个说法



文章来源: Using a dictionary to pass parameters to postgresql statement in python