[ZODB-Dev] Fixing POSKeyErrors :-)

Shane Hathaway shane at hathawaymix.org
Tue Feb 12 19:43:08 EST 2008


Chris Withers wrote:
> Anyway, lets get on and insert our 'broken' marker so that we don't get 
> POSKeyErrors raised:
> 
>  >>> import cStringIO
>  >>> import cPickle
>  >>> import transaction
>  >>> s = app._p_jar.db()._storage
>  >>> file = cStringIO.StringIO()
>  >>> p = cPickle.Pickler(file, 1)
>  >>> p.dump((data.__class__, None))
> <cPickle.Pickler object at 0xb5eb1134>
>  >>> p.dump(data.__getstate__())
> <cPickle.Pickler object at 0xb5eb1134>
>  >>> t = transaction.Transaction()
>  >>> t.description = 'Fix POSKeyError'
>  >>> s.tpc_begin(t)
>  >>> s.store(oid,None,file.getvalue(),'',t)
>  >>> s.tpc_vote(t)
> [('\x00\x00\x00\x00\x00\x00>\n', '\x03s\xb6\xf4AQ\xe7\xdd')]
>  >>> s.tpc_finish(t)

As a slight improvement, something like this should also work (untested):

>>> data._p_jar = app._p_jar
>>> data._p_oid = oid
>>> app._p_jar.register(data)
>>> import transaction
>>> transaction.get().note('Fix POSKeyError')
>>> transaction.commit()

> It's a shame ZODB doesn't turn POSKeyErrors into proper Broken objects 
> as it does when the class can no longer be imported. The problem with 
> POSKeyErrors is that they prevent you accessing *any object that refers 
> to the broken object* not just the missing object itself. This means 
> that when objects *do* go missing, the data loss can be much much worse 
> than it needs to be.
> 
> What does everyone else think?

I'm not sure the situation is as bad as you're suggesting, since I
vaguely recall that inter-object references encode the class of the
referenced object, allowing a parent to load even if its child is gone.

Shane



More information about the ZODB-Dev mailing list