On Feb 12, 2008, at 7:43 PM, Shane Hathaway wrote:

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 think you are right and this should be treated as a bug.

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.


I'm not sure if this is the case for cross-database references. I don't remember the details. Even if it isn't, we should probably create a broken object rather than giving a POSKeyError.

Jim

--
Jim Fulton
Zope Corporation


_______________________________________________
For more information about ZODB, see the ZODB Wiki:
http://www.zope.org/Wikis/ZODB/

ZODB-Dev mailing list  -  ZODB-Dev@zope.org
http://mail.zope.org/mailman/listinfo/zodb-dev

Reply via email to