[Syver Enstad]
I have a Persistent derived class where I want to upgrade from using a PersistentList to a BTrees.IOBTree.IOBTree.
_articleList is the old Persistent list _oidsToArticles is the new IOBTree.
def __setstate__(self, state): articleList = state.get('_articleList') if articleList: oidsToArticles = self.makeBTree() for each in articleList: oidsToArticles[each.oid()] = each del state['_articleList'] state['_oidsToArticles'] = oidsToArticles Persistent.__setstate__(self, state)
This seems to work fine, and I am adding more objects to _oidsToArticles. The problem is that when I commit the transaction, nothing is saved.
Quick guess (untested, untried, just from eyeballing this snippet quickly): nothing is marking self itself as being changed. The only things getting changed are the throw-away in-memory 'state' dict, the throw-away in-memory self.__dict__, and a throw-away in-memory BTree. The primary purpose of p.__setstate__ is to activate a ghost, after which point p is in the up-to-date state (i.e., not changed -- calling Persistent.__setstate__(self, ...) isn't going to mark self as changed, and nothing in the code above modifies self itself). If self doesn't look changed, its state in the DB won't change during commit(), and the DB will still reference your old PersistentList. 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.