Java 数据存储和应用程序版本如何在GAE/J上工作

Java 数据存储和应用程序版本如何在GAE/J上工作,java,google-app-engine,google-cloud-datastore,Java,Google App Engine,Google Cloud Datastore,可以在GAE/J上部署同一应用程序的多个版本,但GAE/J如何处理不同版本可以使用不同数据存储(可能不兼容)方案的事实 例如: 假设在我的应用程序的版本1上有一个POJO(为了简单起见,我省略了几个细节): 现在假设在版本2上我想使用: public class User { private String key; private String username; // on this version, replaced 'phoneNumber' by: private

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

例如:

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

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

public class User {

  private String key;

  private String username;

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

}
现在有两个问题:

  • 如果我从GAE/J部署这两个版本,我将在数据存储中看到什么模式

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

  • 引用

    与关系数据库不同,应用程序 引擎数据存储不需要这样做 给定类型的所有实体都具有 相同的属性。应用程序可以 指定并实施其数据模型 使用SDK附带的库, 或者它自己的代码

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

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

    如果不表示此类约束,那么缺少的属性将要么具有代码或库提供的默认值,要么具有“默认默认值”,我认为在Java中通常是
    null
    ,在Python中是
    None

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

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

    一般来说,我不会担心添加“可选”属性(那些可能合法地丢失了/
    null
    /
    None
    ,或者在这些情况下具有明确的默认值,以便旧版本编写的实体仍然可以正确读取),而是添加其他类型的更改(将以前缺少的或可选的属性改为强制属性、添加其他约束等)可能需要一种形式的“数据库迁移”(可能通过安全数据连接器)或“应用程序级hacks for legacy compatibility”(如果迁移不可行)

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

    因此,在实践中,这不一定是一个简单的问题,但这样想还是有帮助的:数据存储本身没有模式,只有我的应用程序和/或它选择使用的库在应用程序级别对底层实体强制执行所需的任何约束,而这些实体本身确实有一组任意属性--“软模式”,应用程序级架构,基础数据层中没有“实际”架构

    public class User {
    
      private String key;
    
      private String username;
    
      // on this version, replaced 'phoneNumber' by: 
      private String eMail;
    
    }