ndb / Google App Engine上的简单版本/历史记录

时间:2012-05-16 12:46:21

标签: google-app-engine versioning app-engine-ndb

我希望创建一个系统,用于跟踪Google App Engine(Python)上ndb.Models / Expandos内容的版本(历史)。

内容可能相对较长,可能有很多版本,但版本之间的差异可能非常小。我希望其他人做过这样的事情,我想知道他们是如何做到这一点的,以及可以指导设计和原则的原则。发展。

在部署时尚不知道数据模型的属性是什么(例如“标题”,“内容”,“正文”,“日期”等),但类型是已知的(日期) ,文本等)。

我最初的想法是安排这样的事情:

from google.appengine.ext import ndb

class Version(ndb.Expando):
  version_id = ndb.IntegerProperty()
  # dated, etc.
  # data properties are not known in advance, hence Expando

 class MyDoc(ndb.Model):
   head     = ndb.KeyProperty(kind=Version)

   instance = ndb.kind=Property(kind=Version, repeated=True)
   # ^^^ may be a StructuredProperty?

算法概述如下:

保存

每次用户保存文档时,请将所有最新数据放入新的Version并将head指向该实例。

此时或之后的某个时间,通过旧版本并将完整保存更改为差异(以节省空间),例如diff-match-patch。我希望每小时,每天或一些设定时间可以完全保存 - 或者设定一些差异。

载入

加载head非常简单。

旧版本将标记为完整保存或差异,具体取决于数据可以直接返回或从差异编译。

思想?

我相信其他人已经解决了这个问题,我很想知道有什么想法和实施。显然,有完整的版本控制系统,如Git,Mercurial和Subversion以及CVS - 但这些都是针对预期用途的过度杀伤,并且不适用于Google App Engine。

1 个答案:

答案 0 :(得分:2)

一些想法:

  • 您需要为版本提供单调递增的ID,因此您可以对版本实体进行范围查询。这可能意味着您将希望与文档位于同一实体组中的所有历史数据,并将最新版本ID保留在文档实体上或同一组中的单独实体中。如果您希望系统范围内单调增加ID(例如关联或订购对不同组中的多个实体所做的更改),您将需要查看分片计数器和跨组事务。

  • 如果空间足以让您存储差异,我不明白为什么您要将完整版本减少到背景作业的差异,而不仅仅是更新。如果空间不是一个大问题,并且主要特征是能够区分两个任意版本,那么存储完整数据可能更容易,因此差异的成本与中间版本的数量不成比例(或所有版本,如果您的差异介于历史版本之间)。假设您不想对过去版本的属性执行查询,可以通过以紧凑​​形式序列化旧实体并将其存储在非索引blob属性中来节省空间。 (我假设这是你如何存储每个差异,如果你使用差异?)你也可以在每个修订版本的里程碑保留完整的文档,所以两个历史版本之间的差异需要最多2n个版本来计算。

  • 根据您的描述,您似乎更喜欢将MyDoc作为对Version实体的引用,该实体将包含最顶层的数据。也许MyDoc更容易包含最前面的数据(并且其属性用MyDoc键索引等),并且更新只是创建带有先前数据的版本(diff或full)。

  • 不要忘记容纳删除。也许MyDoc消失了(所以它不会出现在键和属性查询中),父路径的最新版本包含完整的最后一个已知文档。

(这只是我的头脑。我为这个CMS工作做了一点思考,但我还没有建立它。)