Executing “SELECT … WHERE … IN …” using MySQLdb

后端 未结 10 1969
耶瑟儿~
耶瑟儿~ 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 22:04

    If you have other parameters in the query, beyond the IN list, then the following extension to JG's answer may be useful.

    ids = [1, 5, 7, 213]
    sql = "select * from person where type=%s and id in (%s)"
    in_ids = ', '.join(map(lambda x: '%s', ids))
    sql = sql % ('%s', in_ids)
    params = []
    params.append(type)
    params.extend(ids)
    cursor.execute(sql, tuple(params))
    

    That is, join all the params in a linear array, then pass it as a tuple to the execute method.

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

    Have been trying every variation on João's solution to get an IN List query to work with Tornado's mysql wrapper, and was still getting the accursed "TypeError: not enough arguments for format string" error. Turns out adding "*" to the list var "*args" did the trick.

    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
    db.query(sql, *args)
    
    0 讨论(0)
  • 2020-11-29 22:13

    Improving on João's and satru's code, I suggest creating a cursor mixin that can be used to build a cursor with an execute that accepts nested iterables and handles them correctly. A better name would be nice, though... For Python3, use str instead of basestring.

    from MySQLdb.cursors import Cursor
    
    class BetterExecuteMixin(object):
        """
        This mixin class provides an implementation of the execute method
        that properly handles sequence arguments for use with IN tests.
        Examples:
        execute('SELECT * FROM foo WHERE id IN (%s) AND type=%s', ([1,2,3], 'bar'))
        # Notice that when the sequence is the only argument, you still need
        # a surrounding tuple:
        execute('SELECT * FROM foo WHERE id IN (%s)', ([1,2,3],))
        """
    
        def execute(self, query, args=None):
            if args is not None:
                try:
                    iter(args)
                except TypeError:
                    args = (args,)
                else:
                    if isinstance(args, basestring):
                        args = (args,)
                real_params = []
                placeholders = []
                for arg in args:
                    # sequences that we treat as a single argument
                    if isinstance(arg, basestring):
                        real_params.append(arg)
                        placeholders.append('%s')
                        continue
                    try:
                        real_params.extend(arg)
                        placeholders.append(','.join(['%s']*len(arg)))
                    except TypeError:
                        real_params.append(arg)
                        placeholders.append('%s')
                args = real_params
                query = query % tuple(placeholders)
            return super(BetterExecuteMixin, self).execute(query, args)
    
    class BetterCursor(BetterExecuteMixin, Cursor):
        pass
    

    This can then be used as follows (and it's still backwards compatible!):

    import MySQLdb
    conn = MySQLdb.connect(user='user', passwd='pass', db='dbname', host='host',
                           cursorclass=BetterCursor)
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM foo WHERE id IN (%s) AND type=%s', ([1,2,3], 'bar'))
    cursor.execute('SELECT * FROM foo WHERE id IN (%s)', ([1,2,3],))
    cursor.execute('SELECT * FROM foo WHERE type IN (%s)', (['bar', 'moo'],))
    cursor.execute('SELECT * FROM foo WHERE type=%s', 'bar')
    cursor.execute('SELECT * FROM foo WHERE type=%s', ('bar',))
    
    0 讨论(0)
  • 2020-11-29 22:16

    this works for me:

    myTuple= tuple(myList)
    sql="select fooid from foo where bar in "+str(myTuple)
    cursor.execute(sql)
    
    0 讨论(0)
提交回复
热议问题