google-app-engine – ndb / Google App Engine上的简单版本/历史记录

我希望创建一个系统来跟踪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?

算法概述如下:

保存

每次用户保存文档时,将所有最新数据放入新版本并指向该实例.

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

载入中

装载头是微不足道的.

较旧的版本将被标记为完整保存或差异,并且取决于哪些数据可以直接返回或从diff编译.

思考?

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

最佳答案 一些想法:

>您需要为版本提供单调递增的ID,因此您可以对版本实体进行范围查询.这可能意味着您将希望与文档位于同一实体组中的所有历史数据,并将最新版本ID保留在文档实体上或同一组中的单独实体中.如果您希望系统范围内单调增加ID(例如关联或订购对不同组中的多个实体所做的更改),您将需要查看分片计数器和跨组事务.
>如果空间足以让你存储差异,我不明白为什么你要将完整版本减少到后台作业的差异,而不仅仅是更新.如果空间不是一个大问题,并且主要特征是能够区分两个任意版本,那么存储完整数据可能更容易,因此差异的成本与中间版本的数量不成比例(或所有版本,如果您的差异介于历史版本之间).假设您不想对过去版本的属性执行查询,可以通过以紧凑​​形式序列化旧实体并将其存储在非索引blob属性中来节省空间. (我假设这是你如何存储每个差异,如果你使用差异?)你也可以在每个修订版本的里程碑保留完整的文档,所以两个历史版本之间的差异需要最多2n个版本来计算.
>从您的描述中,您可能更喜欢MyDoc作为对Version实体的引用,该实体将包含最顶层的数据.也许MyDoc更容易包含最前面的数据(并且其属性用MyDoc键索引等),并且更新只是创建带有先前数据(diff或full)的Version.
>不要忘记容纳删除.也许MyDoc消失了(因此它不会显示在键和属性查询中),并且父路径的最新版本包含完整的最后一个已知文档.

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

点赞