App Engine Datastore中的空列表:Java与Python

12 投票
4 回答
1881 浏览
提问于 2025-04-15 19:35

我在App Engine上有一个Java模型类:

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

当我在Java中保存一个对象Xyz,并且这个对象的uvw集合是空的时,我在appengine的数据存储查看器中看到一个"null"字段。

当我尝试在Python中加载这个对象(通过remote_api),使用下面定义的Python模型类:

class Xyz(db.Model):
    uvw = db.ListProperty(int)

我收到一个"BadValueError: Property uvw is required"的错误。

而当我在Python中保存同一个类的另一个对象,并且这个对象的uvw列表是空的时,数据存储查看器显示一个"missing"字段。

显然,Java和Python对空列表的存储处理方式不同,这导致了对象之间的“不兼容”。

所以我想问:有没有办法可以:

  • 让Java将空列表存储为一个“缺失”的字段,
  • 让Python在加载对象时优雅地接受一个“null”列表作为空列表?

或者有没有其他建议,能让两种语言都能处理空列表字段。

谢谢大家的回答!

4 个回答

0

Java中的Set(集合)之所以这样工作,是因为Java的集合类是引用类型,默认情况下是空的,也就是null。

要真正创建一个空的Set,可以这样声明:

@Persistent
private Set<Long> uvw = new HashSet<Long>();

或者在右边使用其他实现了Set的类。最常用的Set类型是HashSet。还有一些有趣的Set类型,比如两个线程安全的Set:CopyOnWriteArraySetConcurrentSkipListSet;还有有序的Set类型LinkedHashSet和排序的Set类型TreeSet

1

我使用的是低级的Java API,所以我做的可能和别人不太一样。在把一个集合类型的数据结构保存到数据存储之前,我会把它转换成数据存储能够自然处理的格式。主要就是字符串和字节数组。

听起来Java应用引擎把空集合当成了一个空值(null)。而Python没有正确读取这个空值。你可以试着把空集合保存为字符串“empty set”。然后让Python检查数据存储中是否有这个字符串值。如果有的话,它可以分配一个新的空集合;如果没有,它就可以把这个属性当作一个集合来读取。

2

如果你给你的Python属性设置一个默认值,它应该就能正常工作了:

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

撰写回答