[ZODB-Dev] Setting _p_changed on a ghost

Tim Peters tim at zope.com
Fri Aug 26 14:59:40 EDT 2005


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
    transaction.commit()

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).

Doing

        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
object?

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
objects).



More information about the ZODB-Dev mailing list