My Darned Image Again

Carsten Haese carsten.haese at
Tue Dec 8 20:34:20 CET 2009

Victor Subervi wrote:
> Hi;
> I'm having trouble loading my image again. Here's my code:
>       for pic in pics:
>         sql = 'update %s set %s=%s where SKU=%s;' % (store,
> colNamesPics[i], '%s', sku)
>         sql = sql, (MySQLdb.Binary(pics[int(i)]),)
>         cursor.execute(sql, (MySQLdb.Binary(pics[int(i)]),))
>         print sql
>         i += 1

Oh boy, programming by accident strikes again. Your immediate problem is
the line <<sql = sql, (MySQLdb.Binary(pics[int(i)]),)>> wherein you're
reassigning the name <<sql>> to become a 2-tuple consisting of the
string formerly known as <<sql>> and the 1-tuple containing the picture
contents. That line has no business being there. Delete it.

There are also some stylistic problems in your code that aren't actually
wrong, but they make my toenails curl in horror. Please allow me to
improve your code.

First of all, you're iterating over <<pics>>, and assigning the name
<<pic>> to each one, but you're not referring to that name anywhere.
Instead, you use an artificial index counter (<<i>>), which you're then
using to look up the i-th picture. Of course, you need <<i>> to look up
the i-th column name. Instead, you should do a parallel iteration that
iterates over the column name and the picture simultaneously. Look in my
code below for the line containing <<zip>> to see how that's done.

Also, you should only use string interpolation to build the parts of the
query that aren't values. In other words, only the variable table and
column names should be put into the query via string interpolation. The
sku should be passed as a parameter. Also, you should just use "%%s" to
get a literal "%s" through the interpolation step instead of
interpolating "%s" into %s markers.

Putting all that together, I'd rewrite your code above as follows:

for (column_name, pic) in zip(colNamesPics, pics):
    query = ("update %s set %s = %%s where SKU=%%s" %
                (store, column_name) )
    parameters = (MySQLdb.Binary(pic), sku)
    cursor.execute(query, parameters)

There, that's much less cluttered.


Carsten Haese

More information about the Python-list mailing list