在Python中将列表传递给SQL

3

我正试图将一个列表传递给SQL。据我所知,没有针对列表的bind类型。因此,我试图将列表转换为字符串: 这是我尝试执行的SQL:

select a,b,sum(c) as total from t where d in ('x','y') group by 1,2

因为我需要进行参数化,所以我使用了以下代码:

import pandas as pd
import pyodbc
#conn_vertica -- connection object to vertica
f_list = ['x','y']
sql_test=   select a,b,sum(c) as total from t where d in (%s) group by 1,2
l = ', '.join(map(lambda x: '%s',f_list))
sql_test = sql_test % l
df_test = pd.read_sql(sql_test,conn_vertica) # to read it into a dataframe

在运行时,我遇到了一个错误:
pandas.io.sql.DatabaseError: Execution failed on sql 'select a, b, sum(c) as total from t where d in (%s, %s)  group by 1,2': ('42601', '[42601] ERROR 4856:  Syntax error at or near "%" at character 123\n (4856) (SQLExecDirectW)')

有没有关于如何将列表传递给SQL的建议?

在执行完 sql_test = sql_test % l 这行代码后,输出结果如下:select a,b,sum(c) as total from t where d in (%s, %s) group by 1,2 - Data Enthusiast
1个回答

5
您可以将其作为元组传递:
sql_test = "SELECT a, b, SUM(c) AS total FROM t WHERE d IN {0} GROUP BY 1, 2".format(tuple(f_list))

>>> sql_test
"SELECT a, b, SUM(c) AS total FROM t WHERE d IN ('x', 'y') GROUP BY 1, 2"

谢谢@Alexander,它起作用了。还有其他方法可以做到这一点吗?我的方法错了吗? - Data Enthusiast
好的。在我的查询中,我需要传递多个参数。因此,对于第一个参数,我使用了{0}和.format(tupe(list))。对于第二个参数,我尝试使用{1}(这个数字表示参数的位置):查询看起来像这样:sql_test =“SELECT a,b,SUM(c) AS total FROM t WHERE d IN {0} and e = to_date({1},'YYYY-mm-dd') GROUP BY 1, 2”。.format(tuple(f_list),historical_date) historical_date ='2015-05-01'--这是在开始时初始化的。我收到了一个错误消息,说没有to_date(int,unknown)方法。这种用法是错误的吗? - Data Enthusiast
如果这样写...and e = {1}...format(tuple(f_list), historical_date)不行的话,那就是一个pyodbc问题。 - Alexander
我尝试过了...当我打印SQL时..它看起来是这样的。e = 2015-05-01 .........并且错误是:可能需要显式类型转换 ...我尝试使用str(historical_start_date),但它仍然没有带引号打印..有没有办法将其作为字符串打印或者可能附加引号到它上面...即 e = '2015-05-01' - Data Enthusiast
谢谢,它起作用了。我使用了 where e = to_date('{1}','YYYY-MM-DD') ...最后我传递了变量 historical_start_date。 - Data Enthusiast
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接