[ZODB-Dev] Re: zodb does not save transaction

Laurence Rowe l at lrowe.co.uk
Thu May 29 17:53:39 EDT 2008


tsmiller wrote:

>>> I have a bookstore that uses the ZODB as its storage.  It uses qooxdoo as
>>> the client and CherryPy for the server.  The server has a 'saveBookById'
>>> routine that works 'most' of the time.  However, sometimes the
>>> transaction.commit() does NOT commit the changes and when I restart my
>>> server the changes are lost.

>> This sounds like you are using mutable data types (like lists or dicts) in
>> the
>> non-persistence aware variants.

> Christian, thanks for the reply.
> When I save a book I save a dictionary where all of the keys are strings and
> all of the values are strings. But what you say makes sense.  I keep
> thinking that it must have something to do with the data itself.  I will
> check very carefully to make sure that I am not saving anything but strings
> in the book record.  Thanks.  Tom

The problem is not saving things that are not strings, but modifying a 
non persistent object without notifying the parent persistent object 
that a change has happened and it needs to be saved.
e.g.

you have a persistent object (inherits from persistent.Persistent) pobj

 >>> pobj.dict = {}
 >>> transaction.commit()
 >>> pobj.dict['foo'] = 'bar'
 >>> transaction.commit()
 >>> print pobj.dict
{'foo': 'bar'}

#restart your python process
 >>> print pobj.dict
{}

Instead you must either tell zodb the object has changed:

 >>> pobj.dict = {}
 >>> transaction.commit()
 >>> pobj.dict['foo'] = 'bar'
 >>> pbj._p_changed = True # alternatively: pobj.dict = pobj.dict
 >>> transaction.commit()
 >>> print pobj.dict
{'foo': 'bar'}

#restart your python process
 >>> print pobj.dict
{'foo': 'bar'}

Or use a persistence aware replacement.

 >>> from persistent.mapping import PersistentMapping
 >>> pobj.dict = PersistentMapping()
 >>> transaction.commit()
 >>> pobj.dict['foo'] = 'bar'
 >>> transaction.commit()
 >>> print pobj.dict
{'foo': 'bar'}

#restart your python process
 >>> print pobj.dict
{'foo': 'bar'}

The same principles apply to other mutable non-peristent objects, such 
as lists.

Laurence



More information about the ZODB-Dev mailing list