ZODB не может зафиксировать

Я впервые использую ZODB. Просто пытаюсь зафиксировать данные с помощью FileStorage. Но когда я повторяю тот же сценарий во второй раз, я не могу зафиксировать новый объект. Вот мой сценарий

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()

когда я повторяю код еще раз, просто меняя id root['layer']['2c'] и выхожу из питона, второй раз объект не фиксируется. У меня только первый объект. Что может быть причиной.


person Gagan    schedule 18.04.2011    source источник


Ответы (2)


Уровень сохраняемости ZODB обнаруживает изменения, подключаясь к хуку python __setattr__, отмечая постоянный объект как измененный каждый раз, когда вы устанавливаете атрибут.

Но если вы используете примитивный изменяемый объект, такой как словарь Python, тогда механизм сохранения не сможет обнаружить изменения, поскольку атрибут не записывается. У вас есть три варианта решения этой проблемы:

Используйте постоянное сопоставление

Постоянный пакет включает в себя постоянный класс сопоставления, который в основном представляет собой реализацию словаря Python, который является постоянным и обнаруживает изменения напрямую, подключаясь к __setitem__ и другим перехватчикам сопоставления. Объект root в вашем примере представляет собой постоянное отображение.

Чтобы использовать, просто замените все словари постоянными сопоставлениями:

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

Принудительное обнаружение изменений путем срабатывания крючка

Вы можете просто установить ключ снова или на постоянном объекте снова установить атрибут, чтобы принудительно изменить объект:

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

Отметить постоянный объект как измененный

Вы можете установить флаг _p_changed на ближайшем постоянном объекте. Ваш корневой объект - единственный постоянный объект, который у вас есть, все остальное - это словари Python, поэтому вам нужно пометить его как измененный:

root._p_changed = 1
person Martijn Pieters    schedule 18.04.2011
comment
Спасибо, Мартин, установив _p_changed = 1, я могу сохранить новый объект словаря. Я также пройду через PersistentMapping. - person Gagan; 19.04.2011

Вероятно, вам не хватает

root['layer']._p_changed = 1

после модификации dict.

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

person Andreas Jung    schedule 18.04.2011