我正在开发一个用于填充某些巨大形式的应用程序。表单可以属于多个项目。此表格还有两个部分,可以多次填写,如目标和活动,因此表格可以定义许多目标和活动。
我有一个代表项目的类,另一个代表表单,有两个简单的类来表示目标和活动。项目列表包含表格,表格列出了活动和目标。
class Project(persistent.Persistent):
forms = PersistentList()
...
class Form(persistent.Persistent):
objectives = PersistentList()
activities = PersistentList()
...
我的问题是,我计划将这些数据存储在ZODB中,如下所示:
db['projects'] = OOBTree()
db['forms'] = OOBTree()
db['activities'] = OOBTree()
db['objectives'] = OOBTree()
project = Project(...)//fill data with some parameters
form = Form(...)//fill data with some parameters
objective1 = Objective(...)
objective2 = Objective(...)
activity1 = Activitiy(...)
activity2 = Activitiy(...)
form.addObjective(objective1)
form.addObjective(objective2)
form.addActivity(activity1)
form.addActivity(activity2)
project.addForm(form)
db['projects']['projectID'] = project
db['forms']['formID'] = form
db['activities']['activityID'] = activity1
db['activities']['activityID'] = activity2
db['objectives']['objectiveID'] = objective1
db['objectives']['objectiveID'] = ojective2
transaction.commit()
我知道在存储项目时,表单列表也会被持久化,并且表单中的目标和活动列表也是如此。
但是在其他OOBTrees,'形式','活动'和'目标'的情况下会发生什么? 我这样做是为了更容易遍历或寻找个人形式/目标/活动。但我不确定ZODB是否会缓存这些对象,并且只在保存项目时保留它们一次,并保留对该对象的引用。因此,当修改其中任何一个时,所有引用都会更新。 这意味着当执行 db ['forms'] ['formID'] = form 时,OOBTree将指向与项目OOBTree相同的对象,因此不会持久保存相同的对象两次。 这是它的工作方式吗?或者得到重复的持久化对象并且都是独立的实例?
我知道theres repoze catalog来处理索引和东西,但我不需要那么多,只需能够访问一个表单而不必迭代项目。
谢谢!
答案 0 :(得分:3)
是的,只要您存储的目标对象在其继承的某处具有子类persistent.Persistent
的类,对同一对象的任何引用都将指向完全相同(持久)的对象。你不应该像你所描述的那样期待重复。
short-long-version:ZODB使用特殊的pickle技术,在序列化源/引用对象时,它看到引用是一个持久对象,而不是再次存储该对象,它存储了一个类的元组的元组name和目标对象的内部OID。
警告:这只适用于同一个对象数据库。您的应用程序中不应该有跨数据库引用。