[ZODB-Dev] semantics of _v_ attributes?

Shane Hathaway shane at hathawaymix.org
Wed Oct 6 09:33:21 EDT 2010


On 10/06/2010 02:52 AM, Chris Withers wrote:
> Hi All,
>
> I'm trying to fix this bug:
> https://bugs.launchpad.net/zope2/+bug/649605
>
> ...and I'm struggling to find documentation on the semantics of _v_
> attributes.
>
> In particular, surely this code:
>
>               base._p_activate()       # make sure we're not a ghost
>               base.__setstate__(state) # change the state
>               base._p_changed = True   # marke object as dirty
>
> ...should be enough to indicate that all _v_ attributes should be dropped?

No.  That code does not update the object in the current ZODB 
connection.  That code only updates other connections.

> If it isn't, what is the correct way to indicate to Persistent/ZODB that
> all _v_ attribute should be dropped not only for the current object but
> for all occurrences of that object across all connections to the current
> ZODB?

Separate this into two problems.  You have to solve both:

1) You need to update the object in the current connection.

2) You need to update the object in all other connections.

#2 is easy.  All you have to do is set _p_changed (which is set 
automatically whenever you change an attribute) and commit the 
transaction; ZODB will reload the object in the other connections. 
Reloading removes _v_ attributes.

#1 is more interesting, because ZODB does not normally cause the 
connection that changed an object to reload that object.  Therefore, 
your transaction needs to do something that clears your _v_attributes 
manually.  For example, "self._v_cache = None".  ZODB will not do this 
for you.

To summarize, your code should do this:

     self.somedata = something  # Update all other connections
     self._v_cache = None       # Update this connection

That's all you have to do.

If you really, really need to clear all _v_ attributes, then do this:

     self._p_changed = True
     for key in self.__dict__:
         if key.startswith('_v_'):
             del self.__dict__[key]

Shane


More information about the ZODB-Dev mailing list