为Limone内容类型提供ZODB持久化。
项目描述
Limone ZODB是Limone的扩展,它通过ZODB生成可持久化的内容类型。使用方法与Limone相同,只是装饰器和make_content_type函数是从limone_zodb包而不是从limone包导入的
import colander import limone_zodb import persistent class Friend(colander.TupleSchema): rank = colander.SchemaNode(colander.Int(), validator=colander.Range(0, 9999)) name = colander.SchemaNode(colander.String()) class Phone(colander.MappingSchema): location = colander.SchemaNode(colander.String(), validator=colander.OneOf(['home', 'work'])) number = colander.SchemaNode(colander.String()) class Friends(colander.SequenceSchema): friend = Friend() class Phones(colander.SequenceSchema): phone = Phone() @limone_zodb.content_schema class Person(colander.MappingSchema): name = colander.SchemaNode(colander.String()) age = colander.SchemaNode(colander.Int(), validator=colander.Range(0, 200)) friends = Friends() phones = Phones() jake = Person(name='Jake', age=21) assert isinstance(jake, persistent.Persistent)
理由
天真地,人们可能会认为将persistent.Persistent用作内容类型的基类就足够了。然而,可能会发现某些对内容对象的更改无法持久化。例如,如果没有使用limone_zodb,我们可能只是做了如下操作
import limone import persistent @limone.content_type(Person) class PersistentPerson(persistent.Persistent): pass jake = PersistentPerson(name='Jake', age=21)
然后,在另一个事务中
jake.age = 22 # This will persist just fine
虽然这可以在只更改内容对象的直接属性时正常工作,但如果更改深层属性,如上面示例中的friends或phones,那些更改不一定能自动持久化。这并不是由于Limone的特定原因。任何包含嵌套数据结构的对象都可以观察到这种行为。让我们看一下这个不使用Limone的示例
import persistent class C(persistent.Persistent): def __init__(self): self.foo = 'Hello' self.bars = ['tiki', 'biker'] o = C()
假设我们已经将实例o存储在ZODB中,并在另一个事务中检索它,我们可以尝试修改它。如果我们更改o.foo的值并提交事务,ZODB中将写入一个新的o副本,我们的更改将被保存
import transaction o.foo = 'Howdy' # This change will persist transaction.commit()
另一方面,如果我们向o.bars添加一个新值,那么这个更改本身不足以导致新的o值写入ZODB,更改在提交事务时将不会被持久化
o.bars.append('lesbian') # Change does not persist transaction.commit()
这种情况的原因在于 persistent.Persistent 对象的工作方式。 persistent.Persistent 重写了 object 的 __setattr__ 方法,因此当在持久化对象上设置属性时,该对象会通知事务已更改,并在事务提交时写入新的副本。《bars》则只是一个普通的Python列表,不了解持久化。修改这个列表不会将更改通知给事务,所以ZODB不知道需要写入数据库的新内容。
出于同样的原因,对仅涉及嵌套数据结构的 Limone 内容对象的更改将无法通知事务已发生更改。如果这是对象唯一的更改,那么在事务提交时,该对象的新状态将不会写入数据库。
Limone ZODB 通过将元类传递给正常的 Limone 内容类型生成过程来解决此问题,确保对任何级别的 Limone ZODB 内容对象的任何更改都将自动持久化,无需开发者进行任何跳跃。
Limone ZODB 的变更日志
0.1a2 (2011-08-09)
更改了 _MappingNode 的方法解析顺序,以确保在属性赋值时调用 limone 的 __setattr__。
0.1a1 (2011-07-16)
首次 alpha 版本发布。
项目详情
limone_zodb-0.1a2.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | a83719c525c2303ef2da5c303f94a2dc509d0132aad22a340c12ba777fb6f53f |
|
MD5 | 346a124450b4c7f09f9ad693bce65b85 |
|
BLAKE2b-256 | b925850d2faf16c028eb17bfcd54c768f5d6ea249d61a480f9510fa3a79fa68b |