将Python数组转换为SQL in子句
我在Python中有一个值的数组,我需要在SQL查询的IN语句中使用这个数组。这个数组的大小不是固定的。目前我使用简单的字符串替换,但我更希望使用命名绑定变量,这样可以避免SQL注入攻击,并且可以在SQL查询的多个地方引用同一个变量:
我现在的代码(简化的片段):
accts = ['A123', 'B456', 'C789']
acct_list = ','.join(["'%s'" % a for a in accts])
cursor.execute('''
SELECT A,B,C FROM SOME_TABLE WHERE ACCT_CODE IN ({alist})
UNION SELECT A,B,C FROM OTHER_TABLE WHERE ACCT_CODE IN ({alist})
'''.format(alist=acct_list))
理想情况下,我想做这样的事情,但我知道这并不是那么简单:
accts = ['A123', 'B456', 'C789']
cursor.execute('''
SELECT A,B,C FROM SOME_TABLE WHERE ACCT_CODE IN (:alist)
UNION SELECT A,B,C FROM OTHER_TABLE WHERE ACCT_CODE IN (:alist)
''', alist=accts)
到目前为止,我想到的唯一解决方案是这个,但这并不是最理想的,特别是当我还有其他SQL变量时:
accts = ['A123', 'B456', 'C789']
vars = ['acct%d' % int(x+1) for x,a in enumerate(accts)]
vlist = ','.join([':%s' % v for v in vars])
parms = dict(zip(vars, accts))
sql = '''
SELECT A,B,C FROM SOME_TABLE WHERE ACCT_CODE IN ({vlist})
UNION SELECT A,B,C FROM OTHER_TABLE WHERE ACCT_CODE IN ({vlist})
'''.format(vlist=vlist)
cursor.execute(sql, parms)
上面的最后一个代码块让我可以做我需要做的所有事情,包括向查询和参数字典中添加额外的参数,但我觉得这样做有点绕,明明不应该这么复杂。在我把所有代码都改成这个解决方案之前,我想看看这里有没有人知道更“合适”的方法来做到这一点。
1 个回答
0
我没有用过它来做'in'条件,但在插入语句中,如果要插入的项目数量不固定,我会用问号(?)来表示,问号的数量和列表中的元素数量是一样的:
cur.execute("INSERT INTO my_table("+','.join([x for x in field_list])+") VALUES("+"?,"*(len(field_list)-1)+"?)", insert_list)
这样,实际的Python插入字符串看起来是这样的:
cur.execute('''INSERT INTO my_table(a,b,c,d,e,f,g,h,i,j) VALUES(?,?,?,?,?,?,?,?,?,?)''', insert_list)