In IRC yesterday, Stephan Richter was writing a database migration script
that wanted to (re)store the state of every object's current revision.
FileStorage in ZODB 3.5 has a new iteration protocol (see NEWS.txt) to
deliver current revisions, and the relevant (to _this_ msg) part of
Stephen's code was essentially just:

    for each oid in the database:
        obj = connection.get(oid)
        obj._p_changed = True

This didn't work as intended:  setting _p_changed wasn't always enough to
force obj's state to get written out again.  In fact, this happens whenever
obj is a ghost (as all objects are the first time they're loaded):  setting
obj._p_changed to True on a ghost obj has no effect on anything (it doesn't
even change the value returned by a later obj._p_changed).


        obj._p_changed = True

when obj is a ghost appears to be senseless (what could a user possibly
intend by doing this?), and more-or-less by accident the C persistence code
ends up doing nothing in this case (specifically, cPersistence.c's changed()
function just returns 0 whenever the object's state isn't UPTODATE or STICKY
to begin with, and its Per_set_changed() function ends up doing nothing
other than calling changed() when the state is GHOST).

I would like to make it an error (raise a ValueError exception) to attempt
to set obj._p_changed to a true value when obj is a ghost.  Does anyone

My inclination would be to do this for ZODB 3.5, but leave ZODBs 3.4 and 3.2
alone in this respect.  3.2 and 3.4 are in bugfix mode, and I'd rather not
risk breaking anyone's code with this (I don't mind breaking wholly insane
code in a bugfix release, but it's not clear that code accidentally setting
ghost._p_changed to true is necessarily broken -- perhaps it just didn't
want to bother checking first, and didn't care that it was a no-op for ghost

For more information about ZODB, see the ZODB Wiki:

ZODB-Dev mailing list  -

Reply via email to