Google app engine 如何处理数据存储中字段的数据类型更改?

Google app engine 如何处理数据存储中字段的数据类型更改?,google-app-engine,google-bigquery,google-cloud-datastore,objectify,Google App Engine,Google Bigquery,Google Cloud Datastore,Objectify,我找不到任何关于这个的讨论。我特别想知道: 是否可以在Objectify中更改字段的数据类型,例如从List更改为自定义类?(我猜是的。) 是否可以使用诸如@IgnoreLoad或@AlsoLoad之类的注释来忽略旧数据类型中的条目?(或者更一般地说,在移动中将旧条目迁移到新的数据类型?)这是为具有不同名称的字段记录的,但我担心如果名称保持不变,这是不可能的 如果一个字段有两种不同数据类型的条目,是否仍然可以将表加载到BigQuery中(通过数据存储备份) 是否所有旧条目都是null 替代方

我找不到任何关于这个的讨论。我特别想知道:

  • 是否可以在Objectify中更改字段的数据类型,例如从
    List
    更改为自定义类?(我猜是的。)
  • 是否可以使用诸如
    @IgnoreLoad
    @AlsoLoad
    之类的注释来忽略旧数据类型中的条目?(或者更一般地说,在移动中将旧条目迁移到新的数据类型?)这是为具有不同名称的字段记录的,但我担心如果名称保持不变,这是不可能的
  • 如果一个字段有两种不同数据类型的条目,是否仍然可以将表加载到BigQuery中(通过数据存储备份)
  • 是否所有旧条目都是
    null
替代方案是重新加载/保存所有旧条目并使用不同的字段名,但我对上面列出的问题特别感兴趣

  • 你当然可以。但您现有的数据将无法访问。由于字符串列表(或任何其他可序列化的
    类的列表)由Objectify序列化,因此数据存储中的实际数据类型将保持为字符串

  • 正如你所说,这是可能的不同名称。我看不出用相同的值怎么可能,因为所有序列化的东西都是黑盒的。想想看替代解决方案:为什么不将字段的类型更改为字符串,进行转换并将数据类型更改为所需的类型?您必须模仿Objectify的序列化风格,但这应该是可行的。(必须重新考虑这一点,请参见@stickfigure的评论)

  • 是和否。是的,在您的情况下,数据是一个字符串,并且将保持为字符串。但是,如果您在BQ中使用嵌套模式,这将不起作用,因为您的模式发生了更改

  • 没有。当类的所有实体在特定字段中都有空值时,它也将在数据存储查看器中消失


  • Objectify的文档包括一节关于模式迁移的内容:

    使用提供的原语(@OnLoad、@OnSave、@AlsoLoad、@IgnoreSave等),几乎可以进行任何类型的迁移。这是非常具体的变化,你想做的。从概念上讲,最简单的方法是创建一个具有不同名称和新类型的新字段,然后使用@OnLoad方法导入数据。如果要重新命名该字段,可以在第二遍中重新命名

    更复杂的是以“原始”形式导入数据(例如,将字段类型更改为Object),然后使用@OnLoad将其就地转换。这可能很棘手,除非你真的知道自己在做什么,否则可能不是个好主意


    请记住,如果您有一个繁忙的系统,当您切换版本时,旧版本和新版本都会在很短的时间内提供服务。因此,为了避免破坏数据,您的系统需要经过旧版本和新版本都能理解这两种模式的状态。

    谢谢!1.从什么意义上说?2.我不明白你的替代方案。您似乎暗示我要更改为的自定义类将被序列化为字符串,但我不知道这是真的,我不明白这有什么关系。为了澄清,我想防止加载数据类型错误的旧条目。3.那为什么“对我来说是”?比如说,如果我从String改为int,BigQuery就不能处理这个问题,对吗?4.那么,是的,这是相关的吗?一个实际上到处都是空的字段是否不存在?所有问题的答案归结为数据存储中的数据类型(而不是objectify使用的数据类型)。objectify将任何类型的集合或数组序列化为字符串值。因此,底层数据类型始终是字符串和所有集合/数组的字符串。如果将类型更改为基本类型(如long objectify),则无法读取该值,并在下次保存实体时覆盖该值。如果将转储导入bigquery,并且字段中有不同的基元类型,则可能会使用最大公分母,即字符串。至于解决方案:如果新旧格式都可以表示为字符串(字符串、集合、数组),则这将是一种将数据转换为新格式的方法。如果将字段类型设置为string,则会得到原始内容,并且可以根据需要重写该内容。然后,您可以将类型更改为嵌入格式,如果您将数据重写为嵌入格式的话。如果您希望保留数据,则只有在附加字段的情况下才能从复杂类型或字符串切换到不同的基本类型。关于第4点:据我所知,您必须将该实体的所有字段设置为null,并从实体类中删除该字段。这将使该领域消失。但是空值基本上不存在于数据存储中,因为不存储数据是没有意义的(现在这听起来真的很愚蠢-哦,好吧)。好吧,正如我在这个特殊情况下所说的,我不需要保留数据。事实上,我相信如果空列表确实存储为null,那么它在任何地方都是null的。因此,我想我可以自由地更改数据类型,而不会产生负面影响。感谢您将评论扩展到帖子中!我看过那个页面,但它没有讨论在不更改字段名称的情况下更改字段的类型。从你所说的,我想我的第二个问题的答案是否定的(我想我希望@ignoreload接受一些条件,比如数据类型)。我为你添加了一个例子这个例子非常有用。但是我不明白如何在
    importOldFoo
    中指定
    @alsolad(“foo”)字符串值,因为
    foo
    的新值不会是
    String
    类型(即加载已转换的实体时会发生什么情况?)是的,我的错误是,我的错误是,一个连续的时间太长了