MySQLdb cursor.execute formatter
<p>I'm working with Python and MySQLdb library. This is part of a code which has been working for a lot of time.</p>

<p>I was testing if the code executes correctly in other Ubuntu versions since we are planning a SO upgrade.</p>

<p>The following code works fine in Ubuntu 12.04 (our baseline system now with Python 2.7.3), Ubuntu 14.04.5 (Python 2.7.6), but doesn't in Ubuntu 16.04.1 (Python 2.7.12):</p>

<pre><code>def updateOutputPath(path):
    try:
        # Connect to database
        with closing(MySQLdb.connect(host=Constants.database_host,
            user=Constants.database_user, passwd=Constants.database_passwd,
            db=Constants.database_name)) as db:

            # Create a cursor to execute queries
            with closing(db.cursor()) as cursor:
                # Execute query
                cursor.execute('UPDATE configuration SET value=%s WHERE ' +
                    'property=\'OUTPUT_PATH\'', (path))
                # Save changes in the database and close connection
                db.commit()
    except MySQLdb.Error, e:
        print_exception('Database error', e)
        print_db_query(cursor)
</code></pre>

<p>In the <code>cursor.execute</code> statement, I get the following error: not all arguments converted during string formatting.</p>

<p>Obviously, I checked that the only argument is a valid string describing a valid path, just as when executed in other SO versions.</p>

<p>I could just create a string and pass it to the <code>cursor.execute</code> statement and the problem would be over, but I am curious about this problem.</p>

<p>Any idea why?</p>

<p>I also think it could be related to the python-mysqldb library version and not to the Python version. Its version is 1.2.3-1 in Ubuntu 12.04, 1.2.3-2 in Ubuntu 14.04, and 1.3.7-1 in Ubuntu 16.04 (I assume this update is related to the usage of Mysql-server 5.7 in this OS version).</p>

<p>The parameters passed need to be iterables i.e. list or tuple. So it should be <code>(path,)</code> and not <code>(path)</code></p>

<pre><code>cursor.execute('UPDATE configuration SET value=%s WHERE ' +
                    'property=\'OUTPUT_PATH\'', (path,))

&gt;&gt;&gt; path = 'hello'
&gt;&gt;&gt; a = (path)
&gt;&gt;&gt; type(a)
&lt;type 'str'&gt;
&gt;&gt;&gt; b = (path,)
&gt;&gt;&gt; type(b)
&lt;type 'tuple'&gt;
&gt;&gt;&gt; for x in a:
...     print(x)
... 
h
e
l
l
o
&gt;&gt;&gt; for x in b:
...     print(x)
... 
hello
</code></pre>

<p>If you pass <code>(path</code>) it would be the string which will be iterated as each character of path string, and not as items of the tuple, the correct tuple format is <code>(path,))</code></p>

python mysql ubuntu