Update image field

Hello everyone,

I have a NamedBlobImage field in a custom Dexterity type and for some weird reason a few images were stored as NamedFile instead of NamedBlobImage, don't ask me why.... That's been causing me problems with image scales, to a point were I can't even open the edit form.

So, what I'm trying to do, and failing, is to recreate those images with the correct type. Here is what I did:

import transaction
from plone.namedfile.file import NamedBlobImage, NamedFile
noticias = api.content.find(portal_type='ufal.Noticia')

for n in noticias:
    obj = n.getObject()
    if type(obj.image) == NamedFile:
        blob = NamedBlobImage(
            data = obj.image.data,
            filename = obj.image.filename
        )
        obj.image = blob
transaction.commit()

This code runs with no errors, except that it doesn't work, those files are still NamedFile instead of NamedBlobImage.
I've run this code in a BrowserView and in debug session with no success.

I've manage though to update the image in a single object if do it like this in a debug session:

obj = app.site['path']['to']['object']
obj.image = NamedBlobImage(data=obj.image.data, filename=obj.image.filename)
transaction.commit()

I have more than a thousand objects in this situation, so changing one by one it's not a option.

Any ideas??

sorry it's a really obvious idea but are you sure that the code in the if type(obj.image) == is really run ? I'd stuff a print('obj:' + obj.id) after each obj.image=blob to make sure what is done exactly.

Yeah i’m sure its running... i’ve already put the print statement to see if that were the case..
The code runs but the image doesn’t change.

This is very surprising. The only potential weakness I see is that obj.image might be an acquisition wrapper (rather than the object itself) which would let the type(obj.image) == NamedFile fail.

I would run your code in an interactive debugging session (bin/{instance,client1} debug) under the debugger and determine precisely where things go wrong.

I don't know why, but when I changed the code to this it worked.

for n in noticias:
    obj = n.getObject()
    try:
        image = obj.image
        if type(obj.image) == NamedFile:
            obj.image = NamedBlobImage(
                data = image.data, 
                filename = image.filename
            )
    except AttributeError:
        print "No image"
transaction.commit()

Thanks guys.

1 Like

if there is an uncaught exception the transaction is never committed so nothing is changed, that's to be expected.
What is surprising is that code that I presume you ran in the console could throw an uncaught exception without you noticing. I tried to run code generating such exception and it's totally obvious that something is wrong. I don't know how you ran this code to not see it.

Me neither...