如何使用python将预准备语句用于“从xxx中选择xxx”

时间:2013-04-08 16:04:11

标签: python mysql sql prepared-statement

我使用dict来存储条件,键数和值不固定,例如

dict = {}
dict['v1'] = 'abc'
dict['v2'] = 123
...
dict['vn'] = xxx

我的sql格式是

  

从tablename中选择*,其中v1 ='abc'且v2 = 123且... vn = xxx

我试图先把这样的sql转为:

  

sql =“select * from tablename,其中v1 =%s,v2 =%s和... vn =%s”

下面的格式可以避免sql注入,问题是我不知道值的数量,如何编写这个准备好的语句。提前谢谢。

  

cursor.execute(sql,dict [v1],dict [v2],...,dict [vn])

3 个答案:

答案 0 :(得分:1)

也许是矫枉过正,但你可以使用优秀的SqlAlchemy库:

from sqlalchemy.sql import select
from sqlalchemy import create_engine, MetaData, Table
engine = create_engine('mysql://your_connection_string')
meta = MetaData()
table = Table('table_name', meta, autoload=True, autoload_with=engine)
s = select([table])
for key, val in dict.items():
   s = s.where(getattr(table.c, key)==val)
for row in conn.execute(s):
    print row

如果您计划在Python中执行大量SQL,这可能是值得的。

http://docs.sqlalchemy.org/en/latest/core/tutorial.html

答案 1 :(得分:0)

我会使用类似下面的内容来分解执行函数:

def print_test(sql, param1, param2, param3, param4, param5):
    # just output some of the parameters..
    print param2, param3

print_test("whatever", *(i for i in range(5)))

上面是一个简单的例子来说明print_test函数中发生的事情。我假设你想要某种排序,因此OrderedDict非常适合你。然后,您可以简单地导出值,并且顺序将保持一致。将它们作为元组投射,执行函数将展开它所需的内容。

答案 2 :(得分:0)

以下内容应该有效:

sql = 'select * from tablename where ' + ' and '.join(k + ' = %s' for k in data)
cursor.execute(sql, tuple(data.values()))

确保在创建sql字符串和执行语句之间不对dict进行任何修改,因为如果你这样做,排序可能会改变。

请注意,我将您的dict重命名为data,您不应将dict用作变量名,因为它会掩盖内置类型。

我不完全确定是否有必要转换为元组。