StringIO MySQL data blob Image problem

Tim Golden mail at timgolden.me.uk
Thu Sep 6 04:02:58 EDT 2007


dimitri pater wrote:
> Hi,
> the following code works when inserting images in reportlab tables:
> 
> (result4 is a query result)
> a=0
> for i in result4:
>            cfoto = StringIO()
>            cfoto.write(result4[a][9].tostring())
>            dfoto = cfoto.getvalue()
>            fileFoto = open(str(a)+'temp.jpg','wb')
>            fileFoto.write(dfoto)
>            fileFoto.close()
>            foto = Image(str(a)+'temp.jpg')
>            a+=1
> 
>           Do stuff here (insert the Image)
> 
> The problem with this code is that I need to create a unique file
> (str(a)+'temp.jpg'), I tried to use a single temp.jpg but it kept
> using the data from the first record. Tried flush(), truncate(0), but
> it didn't work. (My mistake probably ;-)
> But the images show in the PDF so that's fine for now.

You've obviously already worked this one out, which is
great. But if I might just comment on the code a little
bit, in a spirit of helpful criticism:

* It's not clear (to me) why you're using a StringIO
at all. I'm not familiar with MySQL in particular, but
in general, database interface modules will return a Python
string or possibly a buffer object from a Blob field.
In other words, is there anything to stop you simply
writing "result4[a][9]" directly into a file?

<code>
# ... stuff leading up to:
blob = result4[a][9]
ofile = open ("temp.jpg", "wb")
ofile.write (blob) # (or, possibly, str (blob) if it's a buffer)
ofile.close ()
</code>

* Assuming you're using any recent version of Python,
you can save the extra counter by iterating over
enumerate (result4) which return a 0-based index
and the indexed item as a tuple. In fact, now I look
at it, you're doing the work twice. You're iterating
over result4 but doing nothing with the "i" which
is the result of the iteration. You might do better
with something like this:

<code>
#
# I've used "a", "i" to match your code,
# but more descriptive names are good, such
# as n_result, result or whatever fits your mind.
#
for a, i in enumerate (result4):
   blob = i[9]
   ofile = open ("%d-temp.jpg" % a, "wb")
   ofile.write (blob)
   ofile.close ()

</code>

* Finally, the tempfile module is a good one to use for
temporary files. (Although the xx-temp.jpg solution you
used may be perfectly acceptable for your needs).

In the above, I've avoided quite a few good-practice
issues, such as try-except blocks when writing a file,
or with-blocks in Python 2.5+. The code I've sketched
out is merely a rough-and-ready illustration of a
particular point, not a manual of best practice.

I suspect you may be newish to Python, if not to programming
in general. My comments above aren't intended to be
nitpicks to show up your ignorance, but hopefully hints
which might help you look at alternatives or consider
alternative idioms within Python itself.

Good luck with the PDFs!

TJG



More information about the Python-list mailing list