App Engine数据存储中的空列表:Java vs Python

12

我在App Engine中有以下的Java模型类:

public class Xyz ... {
    @Persistent
    private Set<Long> uvw;
}

在Java中,当我保存一个带有一个空的集合uvw的对象Xyz时,我会得到一个"null"字段(如appengine数据存储器中所列)。 当我尝试通过remote_api在Python中加载同一对象时,该对象由以下Python模型类定义:

class Xyz(db.Model):
    uvw = db.ListProperty(int)
我遇到了一个“BadValueError: Property uvw is required”错误。
在Python中将另一个同类对象保存时,如果uvw列表为空,则数据存储查看器会显示一个“missing”字段。
显然,Java和Python处理空列表的方式不同,并导致“不兼容”的对象。
因此我的问题是:有没有办法:
  • 强制Java将空列表存储为“missing”字段,
  • 强制Python在加载对象时将“null”列表优雅地接受为一个空列表?
或者有任何其他建议来处理两种语言中的空列表字段。
感谢你们的答案!

1
https://cloud.google.com/appengine/docs/legacy/standard/java/datastore/entity-property-reference - Teddy
4个回答

2
如果您为Python属性分配默认值,它应该可以工作:
uvw = db.ListProperty(int, default=[])

1

我使用低级别的Java API,所以我的做法可能会有所不同。但在将集合类型的数据结构保存到数据存储之前,我会将其转换为数据存储自然处理的格式。这主要包括字符串和字节数组。

听起来Java应用引擎将空集解释为null值。而Python无法正确读取此null值。您可以尝试将空集保存为字符串值“empty set”。然后让Python检查数据存储是否保存了该字符串值。如果是,则可以分配一个新的空集;如果不是,则可以将属性读取为集合。


0

这可能对你有用

uvw = db.ListProperty(int, default=[])

这是最常见的解决方法...


0
Java Set的行为是因为Java的集合是引用类型,默认情况下为null。
要实际创建一个空Set,请像这样声明:
@Persistent
private Set<Long> uvw = new HashSet<Long>();

或者在右侧使用Set的其他实现方式。 HashSet 是最常用的 Set 类型。 其他有趣的 Set 类型包括两个线程安全的集合 CopyOnWriteArraySetConcurrentSkipListSet;还有有序集合类型 LinkedHashSet 和排序集合类型 TreeSet


2
谢谢,但是当我将对象保存到数据存储中时,集合是空的,而不是null(我的代码不清楚,我应该在存储对象之前指定集合为空的HashSet)。这里的诀窍是,Appengine数据存储层似乎会在存储时将空集合转换为“null”值,我没有看到任何对此行为的控制。 - Laurent Grégoire
@IOranger:啊,好的。我本来想删除这个回答的,但是我会把它留在这里,这样其他人就不会过一会儿再来说同样的话了。 - Powerlord
1
@LaurentGrégoire 至少现在有一种方法来控制这种行为!要更改默认行为以便您可以使用空列表,请在应用程序初始化期间设置 DATASTORE_EMPTY_LIST_SUPPORT 属性,如下所示: - Teddy
https://cloud.google.com/appengine/docs/legacy/standard/java/datastore/entity-property-reference - Teddy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接