Python TypeError when building query string
Question: I am building a query string.

    
    
    query = "SELECT seqid, date, name, steamid, team, text, type, '%s' as triggerword, '%s' as weight FROM chatlogs WHERE date > '%s' AND text LIKE '%%%s%%' ORDER BY DATE" % (word, weight, self.setting['LAST_RUN_TIME'], word)
    

If I print the string, it returns correctly:

    
    
    SELECT seqid, date, name, steamid, team, text, type, 'hunting_term' as triggerword, '0.01' as weight FROM chatlogs WHERE date > '2012-04-18 23:47:58.439124' AND text LIKE '%hunting_term%' ORDER BY DATE
    

However, it then fails with a TypeError exception: TypeError: not enough
arguments for format string

Full code:

    
    
    import database
    
    mysqldb = database.Connection('localhost','mydb',user='myuser',password='mypass')
    
    word = 'hunting_term'
    weight = 0.01
    setting = dict({'LAST_RUN_TIME':'2012-04-18 23:47:58.439124'})
    
    query = "SELECT seqid, date, name, steamid, team, text, type, '%s' as triggerword, '%s' as weight FROM chatlogs WHERE date > '%s' AND text LIKE '%%%s%%' ORDER BY DATE" % (word, weight, setting['LAST_RUN_TIME'], word)
    print query
    
    for message in mysqldb.query(query):        # This is the line it throws the exception on
        print "A row"
    

database is from the
[tornado](https://github.com/facebook/tornado/blob/master/tornado/database.py)
package


Answer: The issue here is that the eventual call to MySQLdb looks something like this:

    
    
    query = "SELECT seqid, date, name, steamid, team, text, type, 'hunting_term' as triggerword, '0.01' as weight FROM chatlogs WHERE date > '2012-04-18 23:47:58.439124' AND text LIKE '%hunting_term%' ORDER BY DATE"
    db.cursor().execute(query, ())
    

The first argument to `db.cursor().execute()` should be a format string, and
the second argument should be the replacements for that format string, you can
see this in the [MySQLdb docs](http://mysql-
python.sourceforge.net/MySQLdb.html#some-examples). In other words it will
execute the following code:

    
    
    query % ()
    

As you can see, this will cause the same TypeError:

    
    
    >>> query % ()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: not enough arguments for format string
    

This means that any literal `%` that you want MySQL to see needs to be a `%%`
when it is seen by `db.cursor().execute()`, so you should be able to fix this
by changing your original format string to the following:

    
    
    query = "SELECT seqid, date, name, steamid, team, text, type, '%s' as triggerword, '%s' as weight FROM chatlogs WHERE date > '%s' AND text LIKE '%%%%%s%%%%' ORDER BY DATE" % (word, weight, self.setting['LAST_RUN_TIME'], word)
    

However the correct way to do this is to let MySQLdb perform the substitutions
for you, which would change your code to the following:

    
    
    query = "SELECT seqid, date, name, steamid, team, text, type, %s as triggerword, %s as weight FROM chatlogs WHERE date > %s AND text LIKE %s ORDER BY DATE"
    parameters = (word, weight, setting['LAST_RUN_TIME'], '%%%s%%' % word)
    for message in mysqldb.query(query, *parameters):
        print "A row"
    

