跳转到主要内容

为Limone内容类型提供ZODB持久化。

项目描述

Limone ZODBLimone的扩展,它通过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

虽然这可以在只更改内容对象的直接属性时正常工作,但如果更改深层属性,如上面示例中的friendsphones,那些更改不一定能自动持久化。这并不是由于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 (4.5 kB 查看哈希值)

上传时间

支持者

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面