[Zope-dev] ZPatterns: Attribute Providers

Phillip J. Eby pje@telecommunity.com
Thu, 18 Jan 2001 16:54:13 -0500


At 04:57 PM 1/18/01 +0000, Steve Alexander wrote:
>Here's my understanding of how Persistent Attribute Providers work:
>
>Persistent Internal Attribute Provider
>
>   DataSkins and Attributes are ultimately stored like this:
>
>
>    Rack's BTree
>       |
>       |
>       | Slots: key:value
>       |
>       |-('ZPatterns.Rack','Self') : DataSkin instance
>                                     ...which has the attribute __dict__
>                                        containing its attributes
>                                        {'id':object_id,
>                                         'foo':value for foo,
>                                         'bar':value for bar}

The above is correct, for Racks which have the "persistently stored" option
selected on the Storage tab.  This is not true for Racks which use the
"retrieved by accessing attribute ____" option, as then the storage is
presumed to be outside the ZODB, or at least outside the Rack.

A Persistent Internal Attribute provider thus only works if you are using
the "persistently stored" option.



>Persistent External Attribute Provider
>
>    Rack's BTree
>       |
>       |
>       | Slots: key:value
>       |
>       |-('ZPatterns.Rack','Self') : DataSkin instance
>       |                             ...which has the attribute __dict__
>       |                                containing 'id':object_id
>       |-foo:value for attribute foo
>       |-bar:value for attribute bar
>
>
>The key ('ZPatterns.Rack','Self') is the special SelfKey that racks use 
>to ensure there is a unique place in a slot to put the slot's object.

Your statement is correct, but the diagram is wrong.  Try this:

    Rack's BTree
       |
       +---------
       | Object 1:
       |
       | Slots: key:value
       |
       |-('ZPatterns.Rack','Self') : DataSkin instance
       |                             ...which has the attribute __dict__
       |                                containing 'id':object_id
       |
       |-('ZPatterns.AttributeProviders', 'ExternalAttributes'):
       |      {'foo':value for attribute foo, 
       |        'bar':value for attribute bar}
       |
       +---------
       | Object 2...

The above is the general diagram.  Internal attributes are stored in the
instance itself, in the slot ('ZPatterns.Rack','Self').  External
attributes are stored in a dictionary, in the slot
('ZPatterns.AttributeProviders', 'ExternalAttributes').  The "self" slot
does not exist unless the rack is "persistently storing" DataSkins, but the
"attributes" slot can exist whether the instance is stored in the ZODB or not.

In short, you should use an External attribute provider if you want to
store certain of an object's attributes in the ZODB, without requiring the
object itself to be stored in the ZODB.  If you intend to use the Rack's
built-in BTree to store the objects themselves, then you should set the
rack to "stored persistently" and use an Internal provider.