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

时间:2011-10-06 07:28:21

标签: google-app-engine

升级GAE应用程序时,升级数据模型的最佳方法是什么?

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

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

1 个答案:

答案 0 :(得分:6)

处理这种情况的方法很少,而且它们并不相互排斥:

  • 对您的数据存储区进行不间断的更改,并解决它所创建的问题。将新字段插入现有模型类,将字段从必需切换到可选,添加新模型等 - 这些不会破坏与任何现有实体的兼容性。但是,由于这些实体没有神奇地改变以符合新模型(请记住,数据存储区是无模式的数据库),您可能需要一个部分支持旧模型的遗留代码。 例如,如果您添加了新字段,则需要通过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等文库。