zope.generations

软件截图:
zope.generations
软件详细信息:
版本: 4.0.0 Alpha 1
上传日期: 15 Apr 15
许可: 免费
人气: 37

Rating: nan/5 (Total Votes: 0)

zope.generations提供在数据库中更新对象的方式,当该应用程序的模式更改 应用模式基本上是数据的结构中,类ZODB的情况下,或在的情况下,该表的描述的结构一个关系数据库。
详细文档
代是在应用模式变化时更新数据库的对象的一种方式。应用模式基本上是数据的结构中,类ZODB或在关系数据库中的情况下,该表的描述的情况下的结构。
当你改变你的应用程序的数据结构,例如,你改变一个类的现有字段的语义,你将与你的变化之前创建的数据库的问题。有关更详尽的讨论和可能的解决方案,请参阅http://wiki.zope.org/zope3/DatabaseGenerations
我们将使用的组件体系结构,我们需要一个数据库和一个连接:
  >>>进口CGI
 从>>>进口pprint pprint
 从>>>进口zope.interface工具
 从>>>进口ZODB.tests.util DB
  >>> DB = DB()
  >>>康恩= db.open()
  >>>根= conn.root()
试想一下,我们的应用程序是一个Oracle:你可以教它反应词组。让我们保持它的简单,并存储在一个字典中的数据:
  >>>根['答案'] = {'你好':'嗨&你怎么办“,
  ......'?人生的意义“:”42“,
&NBSP; ......“四<?”:“四<五'}
&NBSP; >>>进口交易
&NBSP; >>>器transaction.commit()
初始设置
下面是一些代特定的代码。我们将创建并注册一个SchemaManager。 SchemaManagers负责数据库的实际更新。这其中将只是一个假人。这里的关键是使几代模块意识到,我们的应用程序支持代。
SchemaManager的默认实现不适合这个测试,因为它使用Python模块来管理代。就目前而言,这将是蛮好的,因为我们不希望它做任何事情,只是还没有。
&NBSP;从>>>进口zope.generations.interfaces ISchemaManager
&NBSP;从>>>进口zope.generations.generations SchemaManager
&NBSP; >>>进口zope.component
&NBSP; >>> dummy_manager = SchemaManager(minimum_generation = 0,代= 0)
&NBSP; >>> zope.component.provideUtility(
&NBSP; ... dummy_manager,ISchemaManager,名称='some.app“)
'some.app'是一个唯一的标识符。您应该使用URI或你的包的带点名称。
当您启动Zope和打开一个数据库,一个事件IDatabaseOpenedWithRoot发送。 Zope的注册evolveMinimumSubscriber默认的处理此事件。让我们来模拟这个:
&NBSP; >>>类DatabaseOpenedEventStub(对象):
&NBSP; ...高清__init __(个体经营,数据库):
&NBSP; ... self.database =数据库
&NBSP; >>>事件= DatabaseOpenedEventStub(DB)
&NBSP;从>>>进口zope.generations.generations evolveMinimumSubscriber
&NBSP; >>> evolveMinimumSubscriber(事件)
这个动作的结果是,现在该数据库包含一个事实,即我们的当前模式号为0。当我们更新架构,Zope3将有什么样的出发点是一个想法。在这里,看到了吗?
&NBSP;从>>>进口zope.generations.generations generations_key
&NBSP; >>>根[generations_key] ['some.app']
&NBSP; 0
在现实生活中你不应该直接用此键来打扰,但你应该知道它的存在。
升级方案
回到故事。一段时间的推移和我们的客户之一,被黑客攻击,因为我们忘记了逃跑HTML特殊字符!恐怖!我们必须尽快解决这个问题,而不会丢失任何数据。我们决定使用代来打动我们的同行。
让我们更新架构管理器(删除旧之一,安装一个新的自定义的):
&NBSP;从>>>进口zope.component globalregistry
&NBSP; >>> GSM = globalregistry.getGlobalSiteManager()
&NBSP; >>> gsm.unregisterUtility(前提= ISchemaManager,名称='some.app“)
&NBSP;真
&NBSP; >>>类MySchemaManager(对象):
&NBSP; ...工具(ISchemaManager)
&NBSP; ...
&NBSP; ... minimum_generation = 1
&NBSP; ...代= 2
&NBSP; ...
&NBSP; ...高清演进(个体经营,背景,代):
&NBSP; ...根= context.connection.root()
&NBSP; ...答案=根['答案']
&NBSP; ...如果代== 1:
&NBSP; ...的问题,在answers.items答案():
&NBSP; ...答案[问题] = cgi.escape(答案)
&NBSP; ... ELIF代== 2:
&NBSP; ...的问题,在answers.items答案():
&NBSP; ...德尔答案[问题]
&NBSP; ...答案[cgi.escape(问题)] =答案
&NBSP; ...其他:
&NBSP; ...提高ValueError错误(“无赖”)
&NBSP;根... ['答案'] =#答案持久性平
&NBSP; ...器transaction.commit()
&NBSP; >>>经理= MySchemaManager()
&NBSP; >>> zope.component.provideUtility(经理,ISchemaManager,名称='some.app“)
我们已经设置minimum_generation为1。这意味着,我们的应用将拒绝与旧的数据库比一代1.代属性被设置为2,这意味着,这个SchemaManager知道最新一代的大约为2运行。
演变()是重负荷这里。它的任务是获取数据库一代-1的产生。它得到的上下文有属性'连接',这是对ZODB的连接。你可以用它来改变物体就像这个例子。
在这个特殊的实施产生1逸出的答案(例如,关键的,因为它们可以被任何人输入!),生成2逸出的问题(比如说,不太重要的,因为这些都可以通过授权personell仅输入)。
其实,你并不真正需要自定义实现ISchemaManager的。一个是可用的,我们已经使用了一个虚拟的前面。它使用Python模块组织的Evolver功能。看到它的文档字符串以获取更多信息。
在现实生活中,你将有更复杂的对象结构比这里的人。为了使您的生活更轻松,也有zope.generations.utility提供了两个非常有用的功能:findObjectsMatching()和findObjectsProviding()。他们将通过集装箱掏递归来帮助你寻找你要更新,通过接口或其他一些标准的老物件。他们很容易理解,检查他们的文档字符串。
代行动
因此,我们的愤怒的客户端下载我们最新的代码,并重新启动Zope的。该事件再次自动发送:
&NBSP; >>>事件= DatabaseOpenedEventStub(DB)
&NBSP; >>> evolveMinimumSubscriber(事件)
Shazam的!客户端是幸福的了!
&NBSP; >>> pprint(根['答案'])
&NBSP; {'你好':'嗨&你怎么办?“,
&NBSP;“生命的意义?':'42',
&NBSP;“四”?“:”四<五'}
由于evolveMinimumSubscriber很懒惰,只更新数据库足够让你的应用程序可以使用它(到minimum_generation,那是)。事实上,该标记表明该数据库生成已被撞至1:
&NBSP; >>>根[generations_key] ['some.app']
&NBSP; 1
我们看到,几代人的努力,所以我们决定采取下一步演进到新一代2.让我们看看如何可以手动完成:
&NBSP;从>>>进口zope.generations.generations发展
&NBSP; >>>进化(DB)
&NBSP; >>> pprint(根['答案'])
&NBSP; {'你好':'嗨&你怎么办?“,
&NBSP;“生命的意义?':'42',
&NBSP;“四”?“:”四<五'}
&NBSP; >>>根[generations_key] ['some.app']
&NBSP; 2
进化升级的默认行为,由SchemaManager提供的最新一代。您可以使用参数如何演变()当你想只是为了检查是否需要更新或者如果你想偷懒像我们以前所谓的用户。
序架构经理
频繁的子系统用于组成一个应用程序依赖于其它子系统正常工作。如果这两个子系统提供的模式管理器,它往往有助于了解在其中evolvers将被调用的顺序。这允许一个框架,它的客户端能够在音乐会演变,并且客户端可以知道,该框架将之前或之后进行自身进化。
这可通过控制的模式管理实用程序的名称来完成。架构经理通过整理自己的名字确定的顺序运行。
&NBSP; >>> manager1 = SchemaManager(minimum_generation = 0,代= 0)
&NBSP; >>> manager2 = SchemaManager(minimum_generation = 0,代= 0)
&NBSP; >>> zope.component.provideUtility(
&NBSP; ... manager1,ISchemaManager,名称='another.app“)
&NBSP; >>> zope.component.provideUtility(
&NBSP; ... manager2,ISchemaManager,名称='another.app扩展“)
请注意第一包的名称是用于创建相关程序包命名空间。这不是框架的要求,但方便的图案为这个用法。
让我们进化的数据库,以确定这些世代:
&NBSP; >>>事件= DatabaseOpenedEventStub(DB)
&NBSP; >>> evolveMinimumSubscriber(事件)
&NBSP; >>>根[generations_key] ['another.app']
&NBSP; 0
&NBSP; >>>根[generations_key] ['another.app扩展']
&NBSP; 0
让我们假设由于某种原因,每个子系统都需要添加一个世代,和'another.app延伸“的那一代1取决于”another.app“的第1代。我们需要为每一个他们一直跑,所以我们可以验证结果记录架构经理:
&NBSP; >>> gsm.unregisterUtility(前提= ISchemaManager,名称='another.app“)
&NBSP;真
&NBSP; >>> gsm.unregisterUtility(
&NBSP; ...提供= ISchemaManager,名称='another.app扩展“)
&NBSP;真
&NBSP; >>>类FoundationSchemaManager(对象):
&NBSP; ...工具(ISchemaManager)
&NBSP; ...
&NBSP; ... minimum_generation = 1
&NBSP; ...代= 1
&NBSP; ...
&NBSP; ...高清演进(个体经营,背景,代):
&NBSP; ...根= context.connection.root()
&NBSP; ...订购= root.get('排序',[])
&NBSP; ...如果代== 1:
&NBSP; ... ordering.append(“基础1)
&NBSP; ...打印“基础代1'
&NBSP; ...其他:
&NBSP; ...提高ValueError错误(“无赖”)
&NBSP;根... ['订购'] =订货#平持久性
&NBSP; ...器transaction.commit()
&NBSP; >>>类DependentSchemaManager(对象):
&NBSP; ...工具(ISchemaManager)
&NBSP; ...
&NBSP; ... minimum_generation = 1
&NBSP; ...代= 1
&NBSP; ...
&NBSP; ...高清演进(个体经营,背景,代):
&NBSP; ...根= context.connection.root()
&NBSP; ...订购= root.get('排序',[])
&NBSP; ...如果代== 1:
&NBSP; ... ordering.append('依赖1)
&NBSP; ...打印“依赖性产生1'
&NBSP; ...其他:
&NBSP; ...提高ValueError错误(“无赖”)
&NBSP;根... ['订购'] =订货#平持久性
&NBSP; ...器transaction.commit()
&NBSP; >>> manager1 = FoundationSchemaManager()
&NBSP; >>> manager2 = DependentSchemaManager()
&NBSP; >>> zope.component.provideUtility(
&NBSP; ... manager1,ISchemaManager,名称='another.app“)
&NBSP; >>> zope.component.provideUtility(
&NBSP; ... manager2,ISchemaManager,名称='another.app扩展“)
现在不断发展的数据库的Evolver之前,“another.app扩展”的Evolver将一直运行'another.app“:
&NBSP; >>>事件= DatabaseOpenedEventStub(DB)
&NBSP; >>> evolveMinimumSubscriber(事件)
&NBSP;地基产生1
&NBSP;依赖性产生1
&NBSP; >>>根['订购']
&NBSP; ['地基1','从属1']
安装
在上述的例子中,我们手动初始化的答案。我们不应该这样做手工。该应用程序应能够自动做到这一点。
IInstallableSchemaManager延伸ISchemaManager,提供用于执行intial安装的应用程序的安装方法。这比注册数据库的用户打开一个更好的选择。
让我们定义一个新的模式管理器,包括安装:
&NBSP; >>> gsm.unregisterUtility(前提= ISchemaManager,名称='some.app“)
&NBSP;真
&NBSP;从>>>进口zope.generations.interfaces IInstallableSchemaManager
&NBSP; >>>类MySchemaManager(对象):
&NBSP; ...工具(IInstallableSchemaManager)
&NBSP; ...
&NBSP; ... minimum_generation = 1
&NBSP; ...代= 2
&NBSP; ...
&NBSP; ... DEF安装(个体经营,上下文):
&NBSP; ...根= context.connection.root()
&NBSP;根... ['答案'] = {'你好':'嗨&你怎么办“,
&NBSP; ......'?人生的意义“:”42“,
&NBSP; ......“四<?”:“四<五'}
&NBSP; ...器transaction.commit()
&NBSP; ...
&NBSP; ...高清演进(个体经营,背景,代):
&NBSP; ...根= context.connection.root()
&NBSP; ...答案=根['答案']
&NBSP; ...如果代== 1:
&NBSP; ...的问题,在answers.items答案():
&NBSP; ...答案[问题] = cgi.escape(答案)
&NBSP; ... ELIF代== 2:
&NBSP; ...的问题,在answers.items答案():
&NBSP; ...德尔答案[问题]
&NBSP; ...答案[cgi.escape(问题)] =答案
&NBSP; ...其他:
&NBSP; ...提高ValueError错误(“无赖”)
&NBSP;根... ['答案'] =#答案持久性平
&NBSP; ...器transaction.commit()
&NBSP; >>>经理= MySchemaManager()
&NBSP; >>> zope.component.provideUtility(经理,ISchemaManager,名称='some.app“)
现在,让我们打开一个新的数据库:
&NBSP; >>> db.close()
&NBSP; >>> DB = DB()
&NBSP; >>>康恩= db.open()
&NBSP; >>>'答案'的conn.root()
&NBSP;假
&NBSP; >>>事件= DatabaseOpenedEventStub(DB)
&NBSP; >>> evolveMinimumSubscriber(事件)
&NBSP; >>> conn.sync()
&NBSP; >>>根= conn.root()
&NBSP; >>> pprint(根['答案'])
&NBSP; {'你好':'嗨&你怎么办?“,
&NBSP;“生命的意义?':'42',
&NBSP;“四”?“:”四<五'}
&NBSP; >>>根[generations_key] ['some.app']
&NBSP; 2
在ZODB事务日志指出,我们的安装脚本执行
&NBSP; >>> [。在conn.db it.description它()storage.iterator()] [ - 2]
&NBSP; u'some.app:运行安装代“
(小注:这是不是最后一个记录,因为有两个提交:MySchemaManager进行之一,evolveMinimumSubscriber执行第二个MySchemaManager并不真正需要提交。)

什么是新的在此版本中:

  • 在增加了对Python的支持,3.3
  • 在替换弃用zope.interface.implements使用具有同等zope.interface.implementer装饰。
  • 在丢弃的Python 2.4和2.5的支持。

什么在3.7.1版本新

    这是在开发过程中使用,但确实
  • 在删除扩建部分没有编制的Windows。
  • 在生成脚本中添加一张交易单据。

要求

  • 在Python中

显影剂的其他软件 Zope Corporation and Contributors

zope.file
zope.file

14 Apr 15

zope.index
zope.index

14 Apr 15

zope.proxy
zope.proxy

14 Apr 15

意见 zope.generations

评论没有发现
添加评论
打开图片!