2

可以在 GAE/J 上部署同一应用程序的多个版本,但 GAE/J 如何处理不同版本可以使用不同 Datastore(并且可能不兼容)方案的事实?

例子:

假设在我的应用程序的版本 1 中,我有一个类似 POJO(为简单起见,我省略了几个细节):

public class User {

  private String key;

  private String username;

  private Integer phoneNumber;

}

现在假设我想在版本 2 上使用:

public class User {

  private String key;

  private String username;

  // on this version, replaced 'phoneNumber' by: 
  private String eMail;

}

现在有两个问题:

  1. 如果我部署 GAE/J 的两个版本,我将在数据存储中看到什么架构?

  2. 数据本身呢?如果我在版本 2 上添加用户,我会在版本 1 的数据存储中看到其数据吗?

4

1 回答 1

7

引用文档

与关系数据库不同,App Engine 数据存储区不要求给定种类的所有实体都具有相同的属性。应用程序可以使用 SDK 中包含的库或其自己的代码来指定和强制执行其数据模型。

这也被称为“软模式”——数据存储并不真正模式,但您可以或多或少地通过应用程序级代码(您自己的或在库中)模拟某种软模式。

因此,如果您(通过库或在您自己的代码中)强制执行“此属性必须存在”的约束,并且某个实体实际上没有该属性(因为它是基于不同的“软模式”插入的,例如不同版本的应用程序),那么您将在检查约束时获得应用程序级代码或库选择用来指示违反此软约束的任何异常。

如果您没有表达这样的约束,那么缺少的属性将具有您的代码或库提供的默认值,或者是“默认默认值”,我认为这通常是null在 Java 或NonePython 中。

请注意,应用程序的不同版本可能使用不同的运行时(一些可能是 Java,而另一些可能是 Python),并且不同的运行时仍将使用相同的数据存储,因此 Java 与 Python 的区别在这里并不重要。

在您的具体示例中(没有提供默认值,也没有关于强制存在的断言)我希望从任一版本添加用户将使其在另一个版本中可见,缺少属性被视为null(但可能存在我的限制不知道,在这种情况下,当库尝试验证这些约束并看到它们被违反时,应该会导致异常)。

一般而言,我不会担心添加“可选”属性(那些可能合法地丢失/ null/ None,或者在这些情况下具有显式默认值,以便旧版本编写的实体仍然可以正确读取),但其他类型的更改(使以前缺少或可选的属性成为强制性的,添加其他约束等)可能需要某种形式的“数据库迁移”(可能通过安全数据连接器)或“用于遗留兼容性的应用程序级别黑客”,如果迁移是只是不可行。

迁移可能不可行,特别是如果您需要能够回滚到以前的应用程序版本,例如(确实在这些情况下,其他操作会出现问题,例如删除约束与添加约束一样有问题,因为旧版本可能无法处理在新版本中输入的违反新版本中已删除的约束的数据)。

所以这在实践中不一定是一个简单的问题,但这样思考仍然有帮助:数据存储本身没有模式,只有我的应用程序和/或它选择使用的库在应用程序级别强制执行所需的任何约束底层实体,就其本身而言,每个实体都具有任意属性集——“软模式”、应用程序级模式,在底层数据层中没有“实际”模式。

于 2009-06-28T17:03:29.823 回答