多个应用程序版本的数据转换

问题描述:

升级GAE应用程序时,升级数据模型的最佳方法是什么?多个应用程序版本的数据转换

应用程序的版本号允许分隔多个版本,但这些应用程序版本使用相同的数据存储(根据How to change application after deployed into Google App Engine?)。那么当我用一个不同的数据模型上传一个应用程序版本时会发生什么(我在这里考虑python,但这个问题也应该对Java有效)?我想这应该不是一个问题,如果更改添加一个可为空的字段和一些新的类,所以现有的模型可以扩展没有伤害。但是,如果数据模型发生变化,情况会更加严峻吗?如果现有数据与新数据模型不一致,实际上是否会丢失?

我目前看到的唯一选择是将数据存储设置为维护只读模式,将数据转换为脱机状态并再次部署整个数据。

有处理这个的一些方法,它们不是相互排斥的:

  • 让周围创建了问题,你的数据存储和工作的非重大更改。将新字段插入现有模型类,将字段从必需字段切换到可选字段,添加新模型等 - 这些不会破坏与任何现有实体的兼容性。但是由于这些实体不会奇迹般地改变以符合新模型(请记住,数据存储是一个无模式数据库),您可能需要一个遗留代码来部分支持旧模型。 例如,如果您添加了一个新字段,则需要通过getattr(entity, "field_name", default_value)而不是entity.field_name访问它,以便它不会为旧实体生成AttributeError
  • 逐渐将实体转换为新格式。这很简单:如果您发现仍使用旧模型的实体,请进行适当的更改。在上面的例子中,你会希望把实体回来了添加新的领域:

    if not hasattr(entity, "field_name"): 
        entity.field_name = default_value 
        entity.put() 
    val = entity.field_name # no getattr'ing needed now 
    

    理想的情况下,所有的实体将最终被以这样的方式进行处理,你将能够在某些删除代码转换点。在现实中,总会有一些应该手动转换的剩菜 - 这使我们可以选择第三个选项...

  • 批量转换您的实体为新格式。这背后的物流复杂程度很大程度上取决于要处理的实体数量,您网站的活动,您可以投入到流程中的资源等。请注意,使用简单的MapReduce可能不是最好的主意 - 尤其是如果您使用渐进式转换上述技术。这是因为MapReduce处理所有给定类型的实体(提取它们),而可能只有很小的百分比。因此,可以手动编码转换代码,明确地为旧实体编写查询并且例如使用库如ndb