[ZODB-Dev] BTrees and Mutables, was Re: [IndexedCatalog] bug
in default indexing
Shane Hathaway
shane@zope.com
Tue, 11 Feb 2003 15:24:05 -0500
Casey Duncan wrote:
> An alternative which is perhaps more palatable is to just set the whole
> mutable object into the btree again. Like:
>
> l = tree['bar']
> l.append(4)
> tree['bar'] = l # Trigger list persistance
In fact, if you put simple lists in BTrees, you have to use this
pattern. Setting tree._p_changed will not get the right object stored.
BTrees consist of many objects and you have to notify the right one.
This is a messy problem. To avoid bugs, it's better to put tuples or
persistent objects, rather than lists, in BTrees.
[Christian Reis]
>> - BTrees themselves are mutable objects. However, since they are
>> first-class Python instances, and because they have "magic"
>> properties, there is no requirement to set _p_changed=1 with holding
>> a reference to a changed BTree. I.E.:
>>
>> tree = BTree()
>> obj.tree = tree
>> tree['foo'] = 'foo'
>> # obj has _p_changed set *magically*
This isn't BTree magic, it's ZODB magic. Just to clarify. :-)
>> - If a BTree holds a reference to a non-BTree *mutable* type such as
>> a list, and that list changes, then the *BTree itself* needs to
>> have _p_changed set. I.E.:
>>
>> # Continuing from the above example, with obj.tree = tree
>> tree['bar'] = [1,2,3]
>> tree['bar'].append(4)
>> tree._p_changed = 1
Again, this code snippet isn't quite right. In general, it is not
necessary or useful to set _p_changed when working with BTrees.
>> Now my question is, really, this: does obj, who holds the BTree
>> reference, also require _p_changed to be set, or does the BTree's
>> magic notify the ZODB that obj needs to be saved, too? IOW:
>>
>> # Do we also need this?
>> obj._p_changed = 1
No, you don't need to do this. The obj.tree and obj are in separate
ZODB records, and ZODB only needs to store the records that have changed.
Shane