[ZODB-Dev] know the state of an object

Tim Peters tim.one at comcast.net
Thu Oct 13 19:04:34 EDT 2005


[dvd]
> this my first post to this list, and first of all thanks for your work.
>
> I'm developing a ZODB based Collection Management software, and, for a
> bunch of reasons, i have to know the list of modified objects before the
> current transaction commit. Looking around seems there is no a public
> API to obtains this list

That's true.

> from the connection object,

You didn't say which version of ZODB you're using.  Since you believe a
Connection keeps track of which objects have been modified, I'll assume
you're using ZODB 3.3 or later (which is either true, or your belief about
who keeps track of modified objects is false ;-)).

> so i overload the __setattr__ method in my base-class and keep track
> of the modified objects
>
> But that's the problem, __setattr__ is called also when ZODB loads the
> objects from the storage and reconstructs it, so is there a way to know
> the state of the object (unpickilng, modified, clean etc etc)?

The good news is that obj._p_state reveals the current state of a persistent
object.  The possible values are exposed by the `persistent` module:

>>> import persistent
>>> persistent.GHOST
-1
>>> persistent.UPTODATE
0
>>> persistent.CHANGED
1
>>> persistent.STICKY
2

The possible state transitions are explained in persistent/interfaces.py,
where UPTODATE is called "saved".  For reasons that escape me, it doesn't
admit to the existence of _p_state (maybe that's not an official part of the
API?).

The bad news is that, during the transition from GHOST to UPTODATE (your
"ZODB loads the objects from the storage and reconstructs it"), the state is
temporarily set to CHANGED _before_ code is invoked to materialize the
object's state (and is set to UPTODATE after that's done).  This is to
prevent runaway recursion, but no matter:  while an object is being
unghostified, it (untruthfully) claims to be in the CHANGED state, not the
GHOST state you might expect.

So, in the end, I don't see any hope for you via this route, short of this:
register an object as changed in your __setattr__ without worrying at all
about _why_ __setattr__ was called.  Later, when you "do something" with
your list of modified objects, simply ignore any whose state at that time is
UPTODATE.  Those are exactly the objects whose state got materialized but
didn't change thereafter.




More information about the ZODB-Dev mailing list