使用 AppEngine bulkloader 加载 db.ListProperty()
Posted
技术标签:
【中文标题】使用 AppEngine bulkloader 加载 db.ListProperty()【英文标题】:Loading db.ListProperty() with AppEngine bulkloader 【发布时间】:2011-07-09 04:42:24 【问题描述】:我正在尝试使用 bulkloader 填充 db.ListProperty() 模型字段。
我正在使用如下的导入转换函数:
def parse_array(fn):
def wrapper(value):
return [fn(seg) for seg in re.split("\\,", value) if not seg=='']
return wrapper
配置如下:
import_transform: lib.bulkloader_helpers.parse_array(int)
有些数组是空的,这会导致问题。当我上传时:
BadValueError:不能使用空列表作为属性值;属性 xxx 是 []。
哦哦。好,我们来改一下导入变换函数:
def parse_array(fn):
def wrapper(value):
args[fn(seg) for seg in re.split("\\,", value) if not seg=='']
if args==[]:
return None
else:
return args
return wrapper
现在空列表加载得很好。但是,当应用尝试加载模型时:
BadValueError: 需要属性 xxx
我也不能设置 db.ListProperty(required=False):
google.appengine.ext.db.ConfigurationError: required 必须为 True。
有人建议出路吗?
谢谢,
贾斯汀
【问题讨论】:
【参考方案1】:这是一个已知的bug (Issue 3646) 与 App Engine 开发环境。
一种解决方法是更改(从版本 1.9.6 开始)google.appengine.api.datastore_types.py 的第 1530 行,内容如下:
if not values:
收件人:
if not values_type is list and not values:
之后就可以正常插入了
[]
对于空数组,它应该可以工作。
【讨论】:
【参考方案2】:Google 尚未修复此问题(2013 年 2 月,API 版本 1.7.4),因此这里有一个不涉及修补 AppEngine 代码的解决方法:
首先使用更新后的 import_transform 函数,它返回 None
而不是空列表。然后将实体的 post_import_function
添加到您的 bulkloader.yaml (docs) 以检查 None
的列表属性并将它们从实体中删除,从而将它们设置回空列表:
def post_import(input_dict, instance, bulkload_state_copy):
if instance["list_prop_name"] is None:
del instance["list_prop_name"]
return instance
【讨论】:
【参考方案3】:完全省略 required
参数。如果已提供,则必须设置为 True
,但不提供则为 False
。
【讨论】:
我没有 :required 字段。我尝试将其设置为 False 以查看是否有帮助,但没有运气。为什么我不能从 import_transform 函数返回一个空列表? @Justin 我在任何地方都看不到您的模型定义。它在哪里?以上是关于使用 AppEngine bulkloader 加载 db.ListProperty()的主要内容,如果未能解决你的问题,请参考以下文章