恐怕你需要手動遍歷整個ZODB。如果這些對象是內容對象,你應該能夠使用標準的OFS方法:
from collections import deque
from datetime import datetime
import transaction
from zope.app.component.hooks import setSite
from Testing.makerequest import makerequest
from AccessControl.SecurityManagement import newSecurityManager
from my.newproduct.types import ArchetypesContentType
site_id = 'Plone' # adjust to match your Plone site object id.
admin_user = 'admin' # usually 'admin', probably won't need adjusting
app = makerequest(app)
site = app[site_id]
setSite(site)
user = app.acl_users.getUser(admin_user).__of__(site.acl_users)
newSecurityManager(None, user)
def treeWalker(root):
# stack holds (parent, id, obj) tuples
stack = deque([(None, None, root)])
while stack:
parent, id, next = stack.popleft()
try:
stack.extend((next, id, child) for id, child in next.objectItems())
except AttributeError:
# No objectItems method
pass
yield parent, id, next
count = 0
for parent, id, obj in treeWalker(site):
if isinstance(obj, ArchetypesContentType):
print 'Found content type object {} at {}'.format(id, '/'.join(object.getPhysicalPath()))
obj._p_changed = True # mark it as changed, force a commit
count += 1
if count % 100 == 0:
# flush changes so far to disk to minimize memory usage
transaction.savepoint(True)
print '{} - Processed {} items'.format(datetime.now(), count)
transaction.commit()
這裏假設你已經包括的工作,你周圍掛;嘗試使用ZODB.broken.Broken
對象進行上述操作沒有意義。
上述腳本作爲一個bin/instance run
腳本,運行它,例如:
bin/instance run path/to/this/script.py
你要處理一切在現場,一個相當沉重的過程,會涉及大量的緩存流失和可能是一個潛在的衝突巨大的承諾。真的,您不希望將其作爲通過網絡腳本運行。
感謝Martijn,但由於權限不足,我無法將此代碼作爲ZMI中的python腳本執行。 (RestrictedPython)。我發現將它添加到我的產品的文件系統以允許執行上述操作是很奇怪的,因爲它是一次性任務。 – Frankline 2013-04-12 05:16:39
@Frankline:充實了一些;你*真的*不想通過網絡來運行這個。這是可能的(用'.pop(0)'替換''deque'而不是'.popleft()',而不用'transaction.commit()'和'print'語句),我只是不要我認爲這不是一個好主意。 – 2013-04-12 08:36:21