[Zope] Re: What kind of attributes can be put inside a simple item

Malcolm Cleaton malcolm at jamkit.com
Fri Feb 18 12:04:33 EST 2005


On Fri, 18 Feb 2005 16:25:09 +0100, Marco Bizzarri wrote:
> Andreas Jung wrote:
>> 
>> 
>> --On Freitag, 18. Februar 2005 10:36 Uhr +0100 Marco Bizzarri 
>> <m.bizzarri at icube.it> wrote:
>> 
>>> Hi all.
>>>
>>> I'm little surprised by the possibility to insert non-persistent
>>> instances inside persistent object. I mean:
>> 
>> 
>> Who says that?
>> 
>>>
>>> class Alfa:
>>>     def __init__(self):
>>>         self.x = 1
>>>         self.y = 2
>>>
>>>
>>> class Beta(SimpleItem):
>>>     def __init__(self):
>>>         self.id = 'anId'
>>>         self.anAlfa = Alfa()
>> 
>> 
>> This is working fine.
>> 
>>>
>>>
>>> I always understood that I could not put Alfa instances inside a Beta
>>> class, because the ZODB machinery did not understood how to pickle them.
>>> But I did some experiments recently, and it looks like the above example
>>> should work.
>> 
>> 
>> The problem with persistent objects is that you should know what you are 
>> doing if
>> you use *persistent* objects as attributes.
>> 
>>>
>>> Could anyone provide some insight on this topic?
>>>
>> 
>> First tell us what leads you to the *your* opinion.
>> 
>> -aj
> 
> Nobody actually told me that. I get my opinion from some results 
> obtained working with persistent and non-persisent objects... it was 
> something I was so conviced that I can't remember from where I took it.

It seems to be quite common to learn about the ZODB this way. My first
surfacing on the ZODB list (which is probably a better place for questions
like this) was also to ask about some misconceptions I had developed!

> What could happen if I use persistent object as attributes of other
> persistent objects?

Ok, here's my understanding of how it works.

The ZODB will persist any object reachable from any other object it's
persisting (starting from the root object, leading to all objects in your
database). For whether or not an object can be, or will be, stored, it
doesn't matter whether or not it is descended from Persistent.

What Persistent does control is the granularity of the storage.

When you pickle an object using regular python, you pickle the whole
object graph - the object you started with, all objects reached through
its attributes, all objects reached through *their* attributes, and so on.

Obviously, this wouldn't be a very good strategy for an object database.
You can write useful programs this way - Mailman, for example, stores all
information on a mailing list and its subscribers in a single big pickle -
but trying this with larger data sets would be a big problem.

So, when the ZODB is pickling up an object for storage, it doesn't store
other Persistent objects reached through attributes in the usual way -
instead, these are stored separately, and references to them are stored in
the original object.

If you use non-Persistent persistent objects (ie. objects which will be
stored, but which don't descend from Persistent - some people call these
second-class persistent objects), they will be stored by value as part of
the Persistent object which references them. If they are referenced by
more than one Persistent object, each will end up with its own copy.

At least, this is my *current* understanding; at any point with the ZODB,
an expert may jump out of nowhere and tell you you're wrong - that's the
adventure ;)

Thanks,
Malcolm.

-- 

    [] j a m k i t
      web solutions for charities

         malcolm cleaton
T:  020 7549 0520
F:  020 7490 1152
M:  07986 563852
W: www.jamkit.com




More information about the Zope mailing list