[Syver Enstad, wants to switch an attribute of a Persitent subclass
 From PersistentList to an IOBTree]

[Tim, guessing]
> Quick guess (untested, untried, ...
> Perhaps shuffling the code around would work, a la:
>     Persistent.__setstate__(self, state)
>     articleList = state.get('_articleList')
>     if articleList is not None:
>         # make the BTree in local oidsToArticles as above, then
>         del self._articlelist
>         self._oidsToArticles = oidsToArticles
> The thinking there is that then you've truly modified self, after self has
> been activated.

Nope, sorry, not a chance.  You have truly modified self then, but
__setstate__ is called by magic as part of activation (unghostifying), and
the activation machinery resets self._p_changed after it calls __setstate__.
So same result as your code:  the in-memory version of self has the BTree,
but commit() doesn't change anything about self in the database (again
because self._p_changed is false -- and will be no matter what you try to do
in __setstate__()).

This appears to be one of those "severely underdocumented" minefields.  The
best older thread I found is here:


but it doesn't actually spell out something "that works" in the way you

One possibility is to use any of these __setstate__ implementations
temporarily, in a one-shot database conversion script:  load every object of
your subclass's type, and for each one "obj", after loading it do

    obj._p_changed = True

Note again that setting _p_changed *inside* __setstate__ won't do any good.

Note too that Jim Fulton has a recent proposal for Zope3 in this area:


[Zope URLs are generally so long my mailer refuses to keep them on one line]

Zope-Dev maillist  -  [EMAIL PROTECTED]
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://mail.zope.org/mailman/listinfo/zope )

Reply via email to