在 Plone 中,如何修复缺少 cmf_uid() 注释的 Archetypes 内容?

In Plone, how do I fix Archetypes content that is missing the cmf_uid() annotation?

我正在使用带有 relstorage 的 Plone 4.3,但不知何故我设法丢失了一些内容对象上的 cmf_uid 注释。这会阻止 collective.iterate 签入内容。有没有一种简单的方法可以让 Plone 遍历数据库并在缺少的地方重新添加 cmf_uid?已经尝试 collective.catalogcleanup 无济于事。

这是一个脚本,用于在门户网站(作为 context 传递)中搜索具有非唯一 cmf_uid 的任何 Document。其中许多文档实际上没有 cmf_uid,但索引 cmf_uid 实际上来自父文件夹 Acquisition。由于问题的表现是 plone.app.iterate 无法签入 Document,该脚本仅向似乎具有非唯一性的 Document 类型添加了唯一性 cmf_uid cmf_uid但实际上没有cmf_uid.

虽然这会将 cmf_uid 添加到所有 Document,但仅将属性添加到当前正在结帐中编辑的文档可能就足够了。

"""
Add missing cmf_uid to Archetypes content.

cmf_uid is required to check in working copies of content.
"""

from Products.CMFUid.UniqueIdHandlerTool import UniqueIdError
from Acquisition import aq_inner
from collections import Counter

def add_missing_uids(context):
    """
    context: the portal
    """
    portal_uidhandler = context.portal_uidhandler
    portal_uidgenerator = context.portal_uidgenerator
    catalog = context.portal_catalog
    brains = catalog.unrestrictedSearchResults()
    freq = Counter(x.cmf_uid for x in brains)
    for brain in brains:
        # If it's only in use once then it's unique enough. Otherwise it's
        # probably inheriting its indexed cmf_uid via Acquisition.
        if freq[brain.cmf_uid] < 2 or brain.portal_type != 'Document':
            continue
        ob = aq_inner(brain.getObject())
        if not portal_uidhandler.queryUid(ob):
            print brain.Type, brain.portal_type, brain.getPath()
            for i in range(3):
                try:
                    portal_uidhandler.setUid(ob, portal_uidgenerator())
                    ob.reindexObject()
                    ob.reindexObject(idxs=['modified'])
                    break
                except UniqueIdError:
                    print "RETRY"
            else:
                print "FAIL"