Python Prepared Statements. Problems with SELECT IN

ε祈祈猫儿з 提交于 2019-12-05 13:37:44

You need one placeholder for each item in your parameter list.
You can use string operations to get that part done:

  1. Create one %s for each parameter, and
  2. Join those together with a comma.

In the next step you can pass your two arguments to execute() as recommended in the DB-API documentation.

software_id_string = (1,2,4)
qry = '''SELECT md5 
           FROM software 
          WHERE software_id IN (%s)''' % ','.join(['%s']*len(software_id_string))
# // 'SELECT md5 FROM software WHERE software_id IN (%s,%s,%s)'
cursor.execute(qry, software_id_string)

I recommend creating a type converter for explicit handling of IN clauses. This is the way the psycopg2 module handles it:

from MySQLdb.converters import conversions

class SQL_IN(object):
    def __init__(self, seq):
        self.seq = seq

    @classmethod
    def escape(cls, obj, d):
        return '(' + ','.join((d[type(o)](o, d) for o in obj.seq)) + ')'

# add this before you call MySQLdb.connect()
conversions[SQL_IN] = SQL_IN.escape

Real example:

db = MySQLdb.connect()
cursor = db.cursor()

SQL = "SELECT * FROM emp WHERE emp_id IN %s"
in_values = (1, 2, 3)
cursor.execute(SQL, (SQL_IN(in_values),))
print cursor._last_executed
print cursor.fetchall()

SQL = "SELECT * FROM emp WHERE name IN %s"
in_values = ("bob", "fred")
cursor.execute(SQL, (SQL_IN(in_values),))
print cursor._last_executed
print cursor.fetchall()

Output:

SELECT * FROM emp WHERE emp_id IN (1,2,3)
((1L, 'bob'), (2L, 'larry'), (3L, 'fred'))
SELECT * FROM emp WHERE name IN ('bob','fred')
((1L, 'bob'), (3L, 'fred'))

You want

cursor.execute("SELECT md5 FROM software WHERE software_id IN %s" % software_id_string)

i.e. a % instead of a comma

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!