将python列表传递给SQL查询

时间:2015-07-03 12:31:44

标签: python sql json

res = db.execute("""
SELECT CAST ((SUM(r.SalesVolume)/1000.0) AS decimal(6,1))
FROM RawData r
INNER JOIN Product p
ON r.ProductId = p.ProductId 
INNER JOIN Calendar c
ON r.DayId = c.DayId
WHERE c.WeekCodeInYear BETWEEN 1 AND 12
AND 
c.YearId = 2014
AND p.Distributor IN (%s)
GROUP BY c.WeekCodeInYear """ % _studios)

_studios是一个Python列表,是JSON对象的一部分。它可以理解为:

["WARNER","TF1","GAUMONT","PATHE","STUDIOCANAL","FRANCETV","M6SND"]

但是当我尝试执行此操作时出现错误:

ProgrammingError: (ProgrammingError) (207, "Invalid column name 'u'WARNER', u'TF1', 
u'GAUMONT', u'PATHE', u'STUDIOCANAL', u'FRANCETV', u'M6SND''.DB-Lib error message 20018, 
severity 16:\nGeneral SQL Server error: Check messages from the SQL

然而,数据库具有指定的所有列。我想这与格式有关。但不确定。

在命令提示符下打印时的查询可以看作:

SELECT CAST ((SUM(r.SalesVolume)/1000.0) AS decimal(6,1))
FROM RawData r
INNER JOIN Product p
ON r.ProductId = p.ProductId
INNER JOIN Calendar c
ON r.DayId = c.DayId
WHERE c.WeekCodeInYear BETWEEN 1 AND 12
AND
c.YearId = 2014
AND p.Distributor IN ([u'WARNER', u'TF1', u'GAUMONT', u'PATHE', u'STUDIOCANAL',
u'FRANCETV', u'M6SND'])
GROUP BY c.WeekCodeInYear

我注意到[行中的] p.distributor可能是个问题?

1 个答案:

答案 0 :(得分:1)

这确实是个问题。您正在使用列表的__repr__版本。相反,使用str.join函数将其变为可用的字符串,并结合列表推导来引用字符串:

"""SELECT CAST ((SUM(r.SalesVolume)/1000.0) AS decimal(6,1))
FROM RawData r
INNER JOIN Product p
ON r.ProductId = p.ProductId
INNER JOIN Calendar c
ON r.DayId = c.DayId
WHERE c.WeekCodeInYear BETWEEN 1 AND 12
AND
c.YearId = 2014
AND p.Distributor IN ({})
GROUP BY c.WeekCodeInYear """.format(', '.join(["'" + studio + "'" for studio in _studios]))

但是,如果有更多参数的复杂查询,这将变得非常难以维护和读取。上述解决方案的格式声明已经很难理解,这只会变得更糟。

正如roippi指出的那样,它也容易受到SQL注入攻击。他们也建议使用参数化查询。