可以在GAE / J上部署同一应用程序的多个版本,但是GAE / J如何处理不同版本可以使用不同数据存储(以及可能不兼容)的方案这一事实?
示例:
假设在我的应用程序的第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;
}
现在有两个问题:
如果我同时部署两个版本的GAE / J,我会在数据存储中看到什么模式?
数据本身怎么样?如果我在版本2上添加用户,我会在版本1的数据存储上看到它的数据吗?
答案 0 :(得分:7)
引用the docs,
与关系数据库不同,App 引擎数据存储区不需要 所有给定类型的实体都有 相同的属性。该应用程序可以 指定并实施其数据模型 使用SDK附带的库, 或者它自己的代码。
这也被称为“软模式” - 数据存储区并不真正做模式,但您可以通过应用程序级代码或多或少地模拟一些软模式(您的拥有,或在图书馆里。)
因此,如果您(通过库或您自己的代码)强制执行一个“此属性必须存在”的约束,并且某个实体实际上没有该属性(因为它是基于不同的插入而插入的)软模式“,例如应用程序的不同版本”,然后您将获得应用程序级代码或库选择用于指示违反此软约束的任何异常,在检查约束的位置。
如果你没有表达这样的约束,那么缺少的属性将具有你的代码或库提供的默认值,或者是“默认默认值”,我认为它通常是null
在Java或{ Python中的{1}}。
请注意,不同版本的应用程序可能使用不同的运行时(有些可能是Java,有些可能是Python),不同的运行时仍然使用相同的数据存储区,因此Java与Python的区别是在这里并不重要。
在您的具体示例中(没有提供默认值且没有关于强制存在的断言)我希望从任一版本添加用户将使其从另一个版本可见,缺少属性被视为None
(但是可能存在我不知道的约束,在这种情况下,当库试图验证这些约束并看到它们被违反时会产生异常。
一般而言,我不担心添加“可选”属性(可能合法地丢失/ null
/ null
,或者在这些情况下具有明确的默认值,以便写入实体由旧版本仍然可以正确读取),但其他类型的更改(使先前缺少或可选属性是强制性的,添加其他约束等)可能需要一种形式的“数据库迁移”(可能通过安全数据连接器)如果迁移不可行,则“应用程序级别会破坏旧版兼容性”。
迁移可能不可行,特别是,如果您需要能够回滚到以前的应用程序版本(例如,在那些情况下,其他操作变得有问题,例如删除约束变得像添加约束一样有问题,因为旧的版本可能无法处理在新版本中输入的数据,这些数据违反了新版本中已删除的约束。
所以它在实践中不一定是一个简单的问题,但它仍然有助于这样思考:数据存储本身没有架构,只有我的应用程序和/或它选择使用的库强制执行所需的任何约束基础实体上的应用程序级别,每个实际上都有一组任意属性 - “软模式”,应用程序级模式,底层数据层中没有“实际”模式。