将许多list参数传递给Python中的查询

时间:2018-04-26 11:24:19

标签: python sql

我有三个清单:

countries=['AUSTRALIA', 'FRANCE', 'ITALY']
segments=['little','medium','big','huge']
costumers = ['ERIK','FRANK','BOB', 'JANE']

我必须写这样的东西:

cursor.execute("SELECT COUNTRY, SEGMENT, CUSTOMER, VALUE
WHERE COUNTRY IN ?, SEGMENT IN ?, VALUE IN ?, (countries, segments, costumers))

有什么想法吗?这三个列表可能因每个列表的组件数量而异。

提前致谢!

3 个答案:

答案 0 :(得分:1)

这可以通过以下方式解决:

cursor.execute("SELECT country, segment, customer, value" +
               "WHERE country IN %(1)s, SEGMENT IN %(2)s, VALUE IN %(3)s",
               {"1": tuple(countries), "2": tuple(segments), "3": tuple(customers)})

这可确保您仍然可以获得之前SQL注入的保护。它也不会在字符串上失败。

答案 1 :(得分:0)

您可以这样做:

countries=['AUSTRALIA', 'FRANCE', 'ITALY']
segments=['little','medium','big','huge']
costumers = ['ERIK','FRANK','BOB', 'JANE']

query = ("SELECT COUNTRY, SEGMENT, CUSTOMER, VALUE "
         " WHERE COUNTRY IN ('{}') "
         " AND SEGMENT IN ('{}') "
         " AND VALUE IN ('{}')").format(countries, segments, costumers)
cursor.execute(query)

答案 2 :(得分:0)

这可能看起来比使用字符串格式直接传递值的其他解决方案更多的代码,但它更安全。阅读SQL injection以了解原因。

将值作为参数传递的难度(比字符串格式化更安全)是在传递参数之前查询必须看起来像这样(?的数量根据参数的数量而变化传入):

"SELECT COUNTRY, SEGMENT, CUSTOMER, VALUE FROM SOME_TABLE WHERE COUNTRY IN (?, ?, ?) AND SEGMENT IN (?, ?, ?) AND VALUE IN (?, ?, ?)"

所以你需要使用字符串格式来传递适当的数量?占位符:

countries=['AUSTRALIA', 'FRANCE', 'ITALY']
segments=['little','medium','big','huge']
customers = ['ERIK','FRANK','BOB', 'JANE']
country_placeholders = ','.join('?' for i in range(len(countries)))
segment_placeholders = ','.join('?' for i in range(len(segments)))
customer_placeholders = ','.join('?' for i in range(len(customers)))
query = """
SELECT COUNTRY, SEGMENT, CUSTOMER, VALUE FROM SOME_TABLE WHERE COUNTRY IN ({}) AND SEGMENT IN ({}) AND VALUE IN ({})
""".format(country_placeholders, segment_placeholders, customer_placeholders)

这将为您提供以下查询模板:

"SELECT COUNTRY, SEGMENT, CUSTOMER, VALUE FROM SOME_TABLE WHERE COUNTRY IN (?,?,?) AND SEGMENT IN (?,?,?,?) AND VALUE IN (?,?,?,?)"

现在您只需要执行并传递参数:

params = tuple(countries + segments + customers)
cursor.execute(query, params)