使用 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()的主要内容,如果未能解决你的问题,请参考以下文章

HBase学习之BulkLoad

[How to] HBase的bulkload使用方法

在 Google AppEngine 中读取 Java 资源文件

使用bulkload方式加载数据到HBase(三种方式)

Spark-2.3.2 HBase BulkLoad

Spark 实战系列Spark 使用 BulkLoad 同步数据到 hbase 排序优化