0

我使用字典来存储条件,键的数量和值不固定,例如

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

我的sql格式是

select * from tablename where v1 = 'abc' and v2 = 123 and ... vn = xxx

我试着先把sql变成这样:

sql = "select * from tablename where v1 = %s and v2 = %s and ... vn = %s"

下面的格式可以避免sql注入,问题是我不知道值的个数,这个prepared statements怎么写。提前致谢。

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

4

3 回答 3

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

于 2013-04-08T16:17:35.643 回答
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非常适合您。然后,您可以简单地导出值并且顺序将保持一致。将它们转换为元组,执行函数将展开它需要的内容。

于 2013-04-08T16:09:38.240 回答
0

以下应该有效:

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

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

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

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

于 2013-04-08T16:10:15.857 回答