Executing “SELECT … WHERE … IN …” using MySQLdb

后端 未结 10 1968
耶瑟儿~
耶瑟儿~ 2020-11-29 21:23

I\'m having a problem executing some SQL from within Python, despite similar SQL working fine from the mysql command-line.

The table looks like this:

相关标签:
10条回答
  • 2020-11-29 21:53

    Unfortunately, you need to manually construct the query parameters, because as far as I know, there is no built-in bind method for binding a list to an IN clause, similar to Hibernate's setParameterList(). However, you can accomplish the same with the following:

    Python 3:

    args=['A', 'C']
    sql='SELECT fooid FROM foo WHERE bar IN (%s)' 
    in_p=', '.join(list(map(lambda x: '%s', args)))
    sql = sql % in_p
    cursor.execute(sql, args)
    

    Python 2:

    args=['A', 'C']
    sql='SELECT fooid FROM foo WHERE bar IN (%s)' 
    in_p=', '.join(map(lambda x: '%s', args))
    sql = sql % in_p
    cursor.execute(sql, args)
    
    0 讨论(0)
  • 2020-11-29 21:53

    Maybe we can create a function to do what João proposed? Something like:

    def cursor_exec(cursor, query, params):
        expansion_params= []
        real_params = []
        for p in params:
           if isinstance(p, (tuple, list)):
             real_params.extend(p)
             expansion_params.append( ("%s,"*len(p))[:-1] )
           else:
             real_params.append(p)
             expansion_params.append("%s")
        real_query = query % expansion_params
        cursor.execute(real_query, real_params)
    
    0 讨论(0)
  • 2020-11-29 21:54

    Why not just this in that case?

    args = ['A', 'C']
    sql = 'SELECT fooid FROM foo WHERE bar IN (%s)' 
    in_p  =', '.join(list(map(lambda arg:  "'%s'" % arg, args)))
    sql = sql % in_p
    cursor.execute(sql)
    

    results in:

    SELECT fooid FROM foo WHERE bar IN ('A', 'C')
    
    0 讨论(0)
  • 2020-11-29 21:54

    args should be tuple.

    eg:

    args = ('A','B')
    
    args = ('A',) # in case of single
    
    0 讨论(0)
  • 2020-11-29 21:59

    Very simple:

    Just use the below formation###

    rules_id = ["9","10"]
    
    sql2 = "SELECT * FROM attendance_rules_staff WHERE id in"+str(tuple(rules_id))
    

    note the str(tuple(rules_id)).

    0 讨论(0)
  • 2020-11-29 22:02

    Here is a similar solution which I think is more efficient in building up the list of %s strings in the SQL:

    Use the list_of_ids directly:

    format_strings = ','.join(['%s'] * len(list_of_ids))
    cursor.execute("DELETE FROM foo.bar WHERE baz IN (%s)" % format_strings,
                    tuple(list_of_ids))
    

    That way you avoid having to quote yourself, and avoid all kinds of sql injection.

    Note that the data (list_of_ids) is going directly to mysql's driver, as a parameter (not in the query text) so there is no injection. You can leave any chars you want in the string, no need to remove or quote chars.

    0 讨论(0)
提交回复
热议问题