Is it possible to use plone.api from a script to delete content items?
If so: why this is not working (the items are found, but not deleted)
# bin/instance run find_macfiles.py -O skipshistorie
import plone.api
from zope.component.hooks import setSite
setSite(app['skipshistorie'])
for brain in app.skipshistorie.portal_catalog(id="ds_store"):
obj= brain.getObject()
plone.api.content.delete(obj)
# bin/instance run find_macfiles.py -O skipshistorie
import plone.api
from zope.component.hooks import setSite
setSite(app['mysite'])
import transaction ;
for brain in app.mysite.portal_catalog(id="ds_store"):
obj= brain.getObject()
print('deleting')
try:
#Below line needs a transaction to actually delete the object
plone.api.content.delete(obj)
except Exception as e:
print(f"Error deleting object {obj.absolute_url()}: {e}")
transaction.commit()
In principle you shouldn't do a transaction.commit() in the loop, only at the end. If you have a huge number of items, you can do a transaction.savepoint() each (maybe) 100 loops, to save on memory.
Exactly. If everything works well, commit at the end of the script.
Otherwise, the transaction will be rolled back completely. Such scripts
should run in one transaction - either everything works and the transaction can be committed, otherwise no changes should be committed.
A transaction.savepoint() after N changes might be useful if you modify a bunch a lot of objects in order to snapshot the changes on disk rather than in RAM.
You may also transction.doom() a transaction. In case of an error, you can either raise an exception or mark the transaction as doomed...this means that you may continue with the execution of your code. However, you will never be able to successfully commit the current transaction if marked as doomed earlier (kind of a safety belt).