ZODB not able to commit
Asked Answered
I

2

2

I am using ZODB first time. Just trying to commit the data with FileStorage. But when I do the same script second time I am not able to commit the new object. Here is my script

from ZODB import FileStorage,DB
import transaction    
storage = FileStorage.FileStorage('/tmp/test.fs')
db = DB(storage)
conn = db.open()
root = conn.root()
#root['layer']={}
root['layer']['2b']={"id":'2b','name':'some name'}
transaction.commit()
conn.close()
db.close()
storage.close()

when I repeat the code once again, with just changing the id root['layer']['2c'] and come out of the python, the second time object is not getting committed. I only have first object only. What could be the reason.

Intendant answered 18/4, 2011 at 14:41 Comment(0)
R
5

The ZODB persistence layer detects changes by hooking into the python __setattr__ hook, marking the persistent object as changed every time you set an attribute.

But if you use a primitive mutable object like a python dictionary, then there is no way for the persistence machinery to detect the changes, as there is no attribute being written. You have three options to work around this:

Use a persistent mapping

The persistent package includes a persistent mapping class, which is basically a python dictionary implementation that is persistent and detects changes directly by hooking into __setitem__ and other mapping hooks. The root object in your example is basically a persistent mapping.

To use, just replace all dictionaries with persistent mappings:

from persistent.mapping import PersistentMapping
root['layer'] = PersistentMapping()

Force a change detection by triggering the hook

You could just set the key again, or on a persistent object, set the attribute again to force the object to be changed:

root['layer'] = root['layer']

Flag the persistent object as changed

You can set the _p_changed flag on the nearest persistent object. Your root object is the only persistent object you have, everything else is python dictionaries, so you need to flag that as changed:

root._p_changed = 1
Riata answered 18/4, 2011 at 17:31 Comment(1)
Thanks Martin, by setting _p_changed=1, I am am able to store the new dictionary object. I'll go through the PersistentMapping also.Intendant
D
0

You are likely missing an

root['layer']._p_changed = 1

after modifiying the dict.

http://zodb.org/documentation/guide/prog-zodb.html?highlight=_p_changed#modifying-mutable-objects

Danas answered 18/4, 2011 at 14:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.