plone 3.3.5 から plone 4.0.7 に移行しようとしていますが、すべての FileFields を BlobFields に変換するステップで行き詰まっています。
Plone アップグレード スクリプトは、すべてのネイティブ FileField を正常に変換しますが、手動で変換する必要があるカスタム AT ベースのクラスがいくつかあります。同じエラーにつながる変換を行う2つの方法を試しました。
Plone移行ガイドとソースコード例で概説されているようにschemaextenderを使用する
すべての FileFields の名前を BLOB フィールドに変更してから、次のスクリプトを実行します。
from AccessControl.SecurityManagement import newSecurityManager from AccessControl import getSecurityManager from Products.CMFCore.utils import getToolByName from zope.app.component.hooks import setSite from Products.contentmigration.migrator import BaseInlineMigrator from Products.contentmigration.walker import CustomQueryWalker from plone.app.blob.field import BlobField admin=app.acl_users.getUserById("admin") newSecurityManager(None, admin) portal = app.plone setSite(portal) def find_all_types_fields(portal_catalog, type_instance_to_search): output = {} searched = [] for k in catalog(): kobj = k.getObject() if kobj.__class__.__name__ in searched: continue searched.append(kobj.__class__.__name__) for field in kobj.schema.fields(): if isinstance(field, type_instance_to_search): if kobj.__class__.__name__ in output: output[kobj.__class__.__name__].append(field.__name__) else: output[kobj.__class__.__name__] = [field.__name__] return output def produce_migrator(field_map): source_class = field_map.keys()[0] fields = {} for x in field_map.values()[0]: fields[x] = None class FileBlobMigrator(BaseInlineMigrator): '''Migrating ExtensionBlobField (which is still a FileField) to BlobField''' src_portal_type = source_class src_meta_type = source_class fields_map = fields def migrate_data(self): '''Unfinished''' for k in self.fields_map.keys(): #print "examining attributes" #import pdb; pdb.set_trace() #if hasattr(self.obj, k): if k in self.obj.schema.keys(): print("***converting attribute:", k) field = self.obj.getField(k).get(self.obj) mutator = self.obj.getField(k).getMutator(self.obj) mutator(field) def last_migrate_reindex(self): '''Unfinished''' self.obj.reindexObject() return FileBlobMigrator def consume_migrator(portal_catalog, migrator): walker = CustomQueryWalker(portal_catalog, migrator, full_transaction=True) transaction.savepoint(optimistic=True) walker_status = walker.go() return walker.getOutput() def migrate_blobs(catalog, migrate_type): all_fields = find_all_types_fields(catalog, migrate_type) import pdb; pdb.set_trace() for k in [ {k : all_fields[k]} for k in all_fields]: migrator = produce_migrator(k) print consume_migrator(catalog, migrator) catalog = getToolByName(portal, 'portal_catalog') migrate_blobs(catalog, BlobField)
問題は、次のトレースバックを受け取る self.obj.reindexObject() 行で発生します。
2011-08-09 17:21:12 ERROR Zope.UnIndex KeywordIndex: unindex_object could not remove documentId -1945041983 from index object_provides. This should not happen.
Traceback (most recent call last):
File "/home/alex/projects/plone4/eggs/Zope2-2.12.18-py2.6-linux-x86_64.egg/Products/PluginIndexes/common/UnIndex.py", line 166, in removeForwardIndexEntry indexRow.remove(documentId)
KeyError: -1945041983
> /home/alex/projects/plone4/eggs/Zope2-2.12.18-py2.6-linux-x86_64.egg/Products/PluginIndexes/common/UnIndex.py(192)removeForwardIndexEntry()
191 str(documentId), str(self.id)),
--> 192 exc_info=sys.exc_info())
193 else:
インデックスの再作成をトリガーする行を削除すると、変換は正常に完了しますが、後で手動でカタログのインデックスを再作成しようとすると、変換されたすべてのオブジェクトが見つからなくなり、今何をすべきか少し迷っています。
このサイトには LinguaPlone がインストールされていますが、何か関係があるのでしょうか?