Monday, May 21, 2007

One way to fix POSKeyErrors in Zope on Windows

I just spent much longer than should have been necessary trying to fix a Zope problem so I'm going to document it just in case anyone else has the same problem in the future.

The problem started with Zope raising a POSKeyError exception whenever a certain object was accessed in the Zope Management Interface (ZMI). The object could not be removed from Zope using the ZMI in any way.

Investigation revealed that this exception signifies corruption of the Zope Database (ZODB) due to an object that has become browkn in some way.

We have backups (of course), but this worried me because it happened on our development server and we do so much development that even restoring a half a day old backup means losing a significant amount of work. So I looked for a way of fixing the problem without restoring a backup.

Further investigation revealed that this can be achieved using 'zopectl debug' to interact directly with the ZODB in a Python shell and delete the broken object.

The next hurdle was that zopectl doesn't work on Windows and no prizes for guessing what we use.

The solution was to use PloneShell, which does the same thing as zopectl but also works on Windows.

The final solution once I had my interactive PloneShell shell running and attached to the ZODB, was to replace the corrupt object with a new object:
  • container._setOb(idOfBrokenObject, someNewObject)
then delete the broken object:
  • container._delObject(idOfBrokenObject)
and then commit the changes to the ZODB:
  • get_transaction().commit()

1 comment:

Danny Hope said...

This is good stuff.