NamedFile to NamedBlobFile using transaction to migrate

Good morning, Plone community!

I am in the process of trying to migrate an archetypes FileField over to the dexterity NamedBlobFile. The file transfers successfully, however, i am running into a problem getting the view to display. This is the error I have:

2021-01-08 09:35:28 ERROR Zope.SiteErrorLog 1610116528.090.600301540508 http://localhost:8080/Plone/directory/brown-rhenne-1/first-reappointment/@@edit
Traceback (innermost last):
  Module ZPublisher.Publish, line 138, in publish
  Module ZPublisher.mapply, line 77, in mapply
  Module ZPublisher.Publish, line 48, in call_object
  Module plone.z3cform.layout, line 66, in __call__
  Module plone.z3cform.layout, line 60, in update
  Module z3c.form.form, line 162, in render
  Module zope.browserpage.viewpagetemplatefile, line 51, in __call__
  Module zope.pagetemplate.pagetemplate, line 132, in pt_render
  Module five.pt.engine, line 98, in __call__
  Module z3c.pt.pagetemplate, line 163, in render
  Module chameleon.zpt.template, line 261, in render
  Module chameleon.template, line 171, in render
  Module 15e07ebfb81b5b5346dba864a5a9f1fb.py, line 91, in render
  Module dcd9a3254e94bbffbbb179068b6be223.py, line 1806, in render_titlelessform
  Module dcd9a3254e94bbffbbb179068b6be223.py, line 451, in render_fields
  Module dcd9a3254e94bbffbbb179068b6be223.py, line 126, in render_widget_rendering
  Module dcd9a3254e94bbffbbb179068b6be223.py, line 1069, in render_field
  Module five.pt.expressions, line 161, in __call__
  Module Products.Five.browser.metaconfigure, line 485, in __call__
  Module zope.browserpage.viewpagetemplatefile, line 83, in __call__
  Module zope.browserpage.viewpagetemplatefile, line 51, in __call__
  Module zope.pagetemplate.pagetemplate, line 132, in pt_render
  Module five.pt.engine, line 98, in __call__
  Module z3c.pt.pagetemplate, line 163, in render
  Module chameleon.zpt.template, line 261, in render
  Module chameleon.template, line 171, in render
  Module 0f44a7146c45304890ccb281d5b3eed2.py, line 591, in render
  Module 0f44a7146c45304890ccb281d5b3eed2.py, line 466, in render_widget_wrapper
  Module five.pt.expressions, line 161, in __call__
  Module z3c.form.widget, line 154, in render
  Module zope.browserpage.viewpagetemplatefile, line 51, in __call__
  Module zope.pagetemplate.pagetemplate, line 132, in pt_render
  Module five.pt.engine, line 98, in __call__
  Module z3c.pt.pagetemplate, line 163, in render
  Module chameleon.zpt.template, line 261, in render
  Module chameleon.template, line 191, in render
  Module chameleon.template, line 171, in render
  Module e395f21f55ac39c8135d64d89f83519e.py, line 142, in render
  Module five.pt.expressions, line 154, in __call__
  Module five.pt.expressions, line 126, in traverse
  Module zope.traversing.adapters, line 136, in traversePathElement
   - __traceback_info__: (<NamedFileWidget 'form.widgets.toPresident'>, 'file_content_type')
  Module zope.traversing.adapters, line 50, in traverse
   - __traceback_info__: (<NamedFileWidget 'form.widgets.toPresident'>, 'file_content_type', ())
LocationError: (<NamedFileWidget 'form.widgets.toPresident'>, 'file_content_type')

 - Expression: "widget/@@ploneform-render-widget"
 - Filename:   ... rm-1.2.3-py2.7.egg/plone/app/z3cform/templates/macros.pt
 - Location:   (line 98: col 81)
 - Source:     ... place="structure widget/@@ploneform-render-widget"/>
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 - Expression: "view/file_content_type"
 - Filename:   ... .0.15-py2.7.egg/plone/formwidget/namedfile/file_input.pt
 - Location:   (line 28: col 21)
 - Source:     doc_type view/file_content_type;
                        ^^^^^^^^^^^^^^^^^^^^^^
 - Arguments:  repeat: {...} (0)
               context: <ImplicitAcquisitionWrapper first-reappointment at 0x7f9455b23370>
               exists: True
               views: <ViewMapper - at 0x7f9439543690>
               modules: <TraversableModuleImporter - at 0x7f944f51a9d0>
               args: <tuple - at 0x7f9449500050>
               nothing: <NoneType - at 0x101486e48>
               target_language: <NoneType - at 0x101486e48>
               allow_nochange: True
               default: <object - at 0x7f944f00e1c0>
               request: <instance - at 0x7f9455655d20>
               wrapped_repeat: {...} (0)
               download_url: http://localhost:8080/Plone/directory/brown-rhenne...
               loop: {...} (0)
               template: <ViewPageTemplateFile - at 0x7f9454827850>
               action: nochange
               translate: <function translate at 0x7f9458afded0>
               options: {...} (0)
               view: <NamedFileWidget toPresident at 0x7f943954f910>

I was using transaction in a Plone python view with the following code to migrate the content:

                    faculties = portal_catalog(portal_type="pbAction")
                    for pbAction in faculties:
                        object = pbAction.getObject()
                        print(pbAction.Title)
                        print(facultyobj)
                        transaction.begin()
                        pbActionobj = api.content.create(
                            container=facultyobj,
                            type='pbaction2',
                            id=object.id,
                            appealLetter=object.appealLetter,
                            appealOther=object.appealOther,
                            YearsOfService=object.YearsOfService,
                            managers=object.managers,
                            deptVotesYes=object.deptVotesYes,
                            deptVotesAbstain=object.deptVotesAbstain,
                            deptVotesNo=object.deptVotesNo,
                            collegeVotesYes=object.collegeVotesYes,
                            collegeVotesAbstain=object.collegeVotesAbstain,
                            collegeVotesNo=object.collegeVotesNo,
                            # title=object.title,
                            # description=object.description,
                            moreDocs=object.moreDocs,
                            toPresident=object.toPresident,
                            chairMemo=object.chairMemo,
                            classroomObservations1=object.classroomObservations1,
                            classroomObservations2=object.classroomObservations2,
                            studentEvaluation1=object.studentEvaluation1,
                            studentEvaluation2=object.studentEvaluation2,
                            resume=object.resume,
                            safe_id=True
                        )
                        pbActionobj.manage_setLocalRoles('rnunez', ['Editor'])
                        transaction.commit()
                        print('pbAction Migration Succeeded')

I thank you kindly in advance for your help.

rbrown12

Looks to me like toPresident is not a NamedBlobFile.

If it is already a blob based file it could be enough to fetch the raw blob (not sure how, IIRC there is something like .getBlob on the Archetypes Field).

If it is not already a blob, I would create a new NamedBlobFile and fill it with the data from the old Archetypes field:

from plone.namedfile.file import NamedBlobFile
toPresident = NamedBlobFile(oldrawdata, contentType=oldcontenttype, filename=oldfilename)

I am not 100% sure about the exact way how to get all this from Archetypes file, it's been a while since I used this.

I had a similar problem when loading the image files after the migration.

The full traceback of the error is below:

/Users/rhennebrown/Plone515/zinstance/bin/python /Users/rhennebrown/Plone515/zinstance/bin/instance fg
2021-01-26 10:34:46 INFO ZServer HTTP server started at Tue Jan 26 10:34:46 2021
Hostname: 0.0.0.0
Port: 8080
2021-01-26 10:34:49 INFO DocFinderTab Applied patch version 1.0.5.
/Users/rhennebrown/Plone515/zinstance/products/FacultyCV/init.py:45: DeprecationWarning: package_home is deprecated. import from App.Common instead
from Globals import package_home
/Users/rhennebrown/Plone515/buildout-cache/eggs/plone.app.blob-1.7.4-py2.7.egg/plone/app/blob/content.py:23: DeprecationWarning: MimeTypeException is deprecated. Import from Products.MimetypesRegistry.interfaces instead
from Products.MimetypesRegistry.common import MimeTypeException
/Users/rhennebrown/Plone515/buildout-cache/eggs/plone.portlet.collection-3.3.1-py2.7.egg/plone/portlet/collection/collection.py:2: DeprecationWarning: isDefaultPage is deprecated. Import from Products.CMFPlone instead
from plone.app.layout.navigation.defaultpage import isDefaultPage
/Users/rhennebrown/Plone515/buildout-cache/eggs/Products.CMFPlone-5.1.5-py2.7.egg/Products/CMFPlone/browser/syndication/views.py:17: DeprecationWarning: wrap_form is deprecated. Import from plone.z3cform.layout instead.
from plone.app.z3cform.layout import wrap_form
2021-01-26 10:34:55 WARNING plone.behavior Specifying 'for' in behavior 'Tiles' if no 'factory' is given has no effect and is superfluous.
/Users/rhennebrown/Plone515/buildout-cache/eggs/Zope2-2.13.27-py2.7.egg/OFS/Application.py:102: DeprecationWarning: Expected text
transaction.get().note("Created Zope Application")
/Users/rhennebrown/Plone515/buildout-cache/eggs/Zope2-2.13.27-py2.7.egg/OFS/Application.py:267: DeprecationWarning: Expected text
transaction.get().note(note)
/Users/rhennebrown/Plone515/buildout-cache/eggs/Zope2-2.13.27-py2.7.egg/OFS/Application.py:523: DeprecationWarning: Expected text
transaction.get().note('Prior to product installs')
2021-01-26 10:34:58 INFO Zope Ready to handle requests
/Users/rhennebrown/Plone515/buildout-cache/eggs/Products.CMFCore-2.2.12-py2.7.egg/Products/CMFCore/DirectoryView.py:493: UserWarning: DirectoryView facultycv_styles refers to a non-existing path 'FacultyCV/skins/facultycv_styles'
(self.id, reg_key), UserWarning)
Starting Migration
Creating directory
/Users/rhennebrown/Plone515/buildout-cache/eggs/Zope2-2.13.27-py2.7.egg/Zope2/App/startup.py:344: DeprecationWarning: Expected text
T.note(path)
/Users/rhennebrown/Plone515/buildout-cache/eggs/Zope2-2.13.27-py2.7.egg/Zope2/App/startup.py:357: DeprecationWarning: Expected text
T.setUser(auth_user.getId(), auth_path)
2021-01-26 10:38:49 INFO ExtendedPathIndex Attempt to unindex nonexistent object with id -1716284823
Directory created
/Plone/directory
Brown, Rhenne

2021-01-26 10:38:49 INFO ExtendedPathIndex Attempt to unindex nonexistent object with id -1716284821
Staff created
Brown, Rhenne
2021-01-26 10:38:49 INFO ExtendedPathIndex Attempt to unindex nonexistent object with id -1716284819
Faculty created
First reappointment
pbAction created
Second Reappointment
2021-01-26 10:38:49 INFO ExtendedPathIndex Attempt to unindex nonexistent object with id -1716284815
pbActionCLT created
Third Reappointment
2021-01-26 10:38:50 INFO ExtendedPathIndex Attempt to unindex nonexistent object with id -1716284813
pbActionLeave created
Third Reappointment
2021-01-26 10:38:50 INFO ExtendedPathIndex Attempt to unindex nonexistent object with id -1716284811
pbActionPortfolio0 created
Fourth Reappointment
2021-01-26 10:38:50 INFO ExtendedPathIndex Attempt to unindex nonexistent object with id -1716284809
pbActionPortfolio0 created
Fifth Reappointment
2021-01-26 10:38:51 INFO ExtendedPathIndex Attempt to unindex nonexistent object with id -1716284807
pbActionPortfolio1 created
Sixth Reappointment
2021-01-26 10:38:51 INFO ExtendedPathIndex Attempt to unindex nonexistent object with id -1716284805
pbActionPortfolio2 created
Seventh Reappointment
2021-01-26 10:38:51 INFO ExtendedPathIndex Attempt to unindex nonexistent object with id -1716284803
pbActionScholar created
/Users/rhennebrown/Plone515/buildout-cache/eggs/zope.deprecation-4.3.0-py2.7.egg/zope/deprecation/deprecation.py:88: DeprecationWarning: isDefaultPage is deprecated. Import from Products.CMFPlone.defaultpage instead
name)
/Users/rhennebrown/Plone515/buildout-cache/eggs/Chameleon-2.25-py2.7.egg/chameleon/tal.py:471: DeprecationWarning: Using len() is deprecated. Use the length attribute for the size of the current page, which is what we return now. Use the sequence_length attribute for the size of the entire sequence.
iterable = list(iterable) if iterable is not None else ()
2021-01-26 10:38:56 ERROR plone.namedfile.scaling Could not scale "<Image at /Plone/portal_college/brown-rhenne/image used for /Plone/directory/brown-rhenne>" of <bound method Staff.absolute_url of <Staff at /Plone/directory/brown-rhenne>>
Traceback (most recent call last):
File "/Users/rhennebrown/Plone515/buildout-cache/eggs/plone.namedfile-4.2.6-py2.7.egg/plone/namedfile/scaling.py", line 253, in call
**parameters
File "/Users/rhennebrown/Plone515/buildout-cache/eggs/plone.namedfile-4.2.6-py2.7.egg/plone/namedfile/scaling.py", line 200, in create_scale
**parameters
File "/Users/rhennebrown/Plone515/buildout-cache/eggs/plone.scale-3.0.3-py2.7.egg/plone/scale/scale.py", line 55, in scaleImage
image = PIL.Image.open(image)
File "/Users/rhennebrown/Plone515/buildout-cache/eggs/Pillow-5.4.1-py2.7-macosx-10.9-x86_64.egg/PIL/Image.py", line 2640, in open
fp = io.BytesIO(fp.read())
AttributeError: 'Image' object has no attribute 'read'
2021-01-26 10:38:57 ERROR plone.namedfile.scaling Could not scale "<Image at /Plone/portal_college/brown-rhenne-1/image used for /Plone/directory/brown-rhenne-1>" of <bound method Faculty.absolute_url of <Faculty at /Plone/directory/brown-rhenne-1>>
Traceback (most recent call last):
File "/Users/rhennebrown/Plone515/buildout-cache/eggs/plone.namedfile-4.2.6-py2.7.egg/plone/namedfile/scaling.py", line 253, in call
**parameters
File "/Users/rhennebrown/Plone515/buildout-cache/eggs/plone.namedfile-4.2.6-py2.7.egg/plone/namedfile/scaling.py", line 200, in create_scale
**parameters
File "/Users/rhennebrown/Plone515/buildout-cache/eggs/plone.scale-3.0.3-py2.7.egg/plone/scale/scale.py", line 55, in scaleImage
image = PIL.Image.open(image)
File "/Users/rhennebrown/Plone515/buildout-cache/eggs/Pillow-5.4.1-py2.7-macosx-10.9-x86_64.egg/PIL/Image.py", line 2640, in open
fp = io.BytesIO(fp.read())
AttributeError: 'Image' object has no attribute 'read'

Thank you for your help, @jensens . I was able to fix the problem by using

NamedBlobImage(data=object.image.data, filename=unicode(object.image.filename))

and

NamedBlobFile(data=object.toPresident.data, filename=unicode(object.toPresident.filename)).

1 Like