[Zope] Acquiring parent objects through BTrees

Chris McDonough chrism@digicool.com
Tue, 07 Aug 2001 22:32:42 -0400


Joseph Barillari wrote:
> 
> Hello,
> 
> I would like to know if it is possible for an object stored in a BTree
> to use acquisition to see its parent object (either the BTree itself
> or the object that holds the BTree).
> 
> Here's an example of what I've tried:
> 
> Python 2.1.1 (#1, Jul 29 2001, 19:04:01)
> [GCC 2.96 20000731 (Red Hat Linux 7.1 2.96-85)] on linux2
> Type "copyright", "credits" or "license" for more information.
> >>> from Acquisition import Implicit
> >>> from BTree import BTree
> >>>
> >>> class A(Implicit):
> ...     pass
> ...
> >>> class B(Implicit):
> ...     pass
> ...
> >>> class D(Implicit, BTree):
> ...     pass
> ...
> >>> a = A()
> >>>
> >>> a.d = D()
> >>> a.d
> <D instance at 8118330>
> >>> a.d.aq_parent
> <A instance at 8114c28>
> >>> a.d[1] = B()
> >>> a.d[1]
> <B instance at 8114c18>
> >>> a.d[1].aq_parent
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
> AttributeError: aq_parent
> 
> The Acquisition machinery has no problem with the regular
> objects. Class D, which wraps a BTree and implicit acquisition, lets
> the BTree see its parents, but an acquisition-enabled object placed in
> an acquisition-enabled BTree still can't see its parent.
> 
> Any suggestions? Or is this a bad idea? Should I implement another
> mechanism? The number of objects stored in the BTrees in the final
> product is unlikely to be more than a few hundred, so another data
> type might work.

You should likely try another mechanism.  A BTree's items don't consider
the BTree to be their acquisition parent.  And it's bad form to manually
wrap them (via a = a.__of__(btreeinstance); btreeinstance['a'] =a)
because when you stick an acquisition-wrapped object into a BTree, the
buckets inside a BTree will eventually be committed to storage and
aquisition wrappers can't be stored inside ZODB.

Try storing a tuple as the value inside the BTree where the first
element of the tuple is the path to the object you want to be the
acqusition parent of the object you're storing, and the second element
is the object (.e.g. ('/FolderA/SubfolderB', <object A>)), then use
restrictedTraverse to get the object related to the path and manually
wrap the object that is the second element in the one you get from
restrictedTraverse (via __of__, e.g... path, ob = tup; ob =
ob.__of__(self.restrictedTraverse(path)).

-- 
Chris McDonough                    Zope Corporation
http://www.zope.org             http://www.zope.com
"Killing hundreds of birds with thousands of stones"