App Engine Datastore中的空列表:Java与Python
我在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 个回答
Java中的Set(集合)之所以这样工作,是因为Java的集合类是引用类型,默认情况下是空的,也就是null。
要真正创建一个空的Set,可以这样声明:
@Persistent
private Set<Long> uvw = new HashSet<Long>();
或者在右边使用其他实现了Set
的类。最常用的Set类型是HashSet
。还有一些有趣的Set类型,比如两个线程安全的Set:CopyOnWriteArraySet
和ConcurrentSkipListSet
;还有有序的Set类型LinkedHashSet
和排序的Set类型TreeSet
。
我使用的是低级的Java API,所以我做的可能和别人不太一样。在把一个集合类型的数据结构保存到数据存储之前,我会把它转换成数据存储能够自然处理的格式。主要就是字符串和字节数组。
听起来Java应用引擎把空集合当成了一个空值(null)。而Python没有正确读取这个空值。你可以试着把空集合保存为字符串“empty set”。然后让Python检查数据存储中是否有这个字符串值。如果有的话,它可以分配一个新的空集合;如果没有,它就可以把这个属性当作一个集合来读取。
如果你给你的Python属性设置一个默认值,它应该就能正常工作了:
uvw = db.ListProperty(int, default=[])