【问题标题】:Importing a dict to an App Engine ndb.JsonProperty with bulkloader使用 bulkloader 将 dict 导入 App Engine ndb.JsonProperty
【发布时间】:2014-03-14 21:37:25
【问题描述】:

我正在使用批量加载器将数据上传到我的 App Engine 数据存储中。

我似乎无法将字典存储到 JsonProperty 中,并且出现以下错误:

BadValueError:不支持的属性类型 near_countries:

我的模型将此属性定义为 JsonProperty:

nearby_countries = ndb.JsonProperty()

我发现的唯一解决方法似乎是存储我的值的 json.dumps(),但我想这基本上是存储字典的字符串表示,而不是字典本身。

我对 JsonProperty 的理解是它需要一个 python 对象作为值,我不应该为 ndb 将处理的 JSON 序列化而烦恼。我说的对吗?

Value 是一个 Python 对象(例如一个列表或一个字典或一个字符串),可以使用 Python 的 json 模块进行序列化; Datastore 将 JSON 序列化存储为 blob。

【问题讨论】:

    标签: google-app-engine app-engine-ndb bulkloader


    【解决方案1】:

    经过大量尝试和错误以及在谷歌上搜索类似帖子后,我设法找到以下帖子,引导我找到以下解决方案:

    http://blog.thekensta.com/2012/06/google-app-engine-bulk-loader-and-ndb.html

    简而言之,JsonProperties 存储为 blob,我们需要向 bulkloader 传递正确的转换方法以从 json 字符串生成 blob。我们可以使用transform.blobproperty_from_base64(来自google.appengine.ext.bulkload.transform模块)

    所以我将我的列表或字典转换为字符串 JSON 字符串表示形式,然后将其转换为 blob,以便批量加载器可以存储它:

    import_transform: "lambda x: transform.blobproperty_from_base64(base64.b64encode(bytes(json.dumps(x.strip(' ,').split(',')))))"

    同样的推理修复了保存为字符串的 TextProperty(在我上面的评论中提到)。您需要使用db.Text 作为转换函数:

    import_transform: db.Text

    为了保存 repeated=True TextProperty,我实际上还必须将其转换为 blob:

    import_transform: "lambda x: transform.blobproperty_from_base64(base64.b64encode(bytes(json.dumps(x.strip(' ,').split(',')))))"

    (在上面的示例中,我实际上将逗号分隔的字符串转换为要存储在 TextProperty(repeated=True) 中的 Text 对象列表

    【讨论】:

      【解决方案2】:

      总的来说,您对 JsonProperty 的看法是正确的。然而,散装装载机是特殊的。老实说,我不太了解它是如何工作的,但在这种情况下,如果它要求您自己调用 json.dumps(),我不会感到惊讶。

      【讨论】:

      • 谢谢。问题是当我自己调用 json.dumps() 时,字符串存储在数据存储中,而不是 blob。我可以在管理控制台中看到存储的值,尽管该属性被定义为 JsonProperty,这应该会导致存储一个二进制文件。并且稍后加载这个属性时,它会抱怨它不是 JSON 对象。
      • 我实际上认为这可能与批量加载程序验证有关。任何人都知道在哪里可以找到它,我会尝试看看我们是否可以丢失它以确保我的 在 JsonProperty 中被接受。我发现的唯一其他解决方法是首先通过 bulkloader 将字符串导入 TextProperty,然后运行一个脚本,该脚本将从字符串创建 并将其存储到 JsonProperty。虽然不是最佳的。
      • bulkloader 的某些验证肯定存在问题。我也收到以下错误:属性 XXXX 太长。最大长度为 500。对于声明为 TextProperty 的属性 XXXX(默认情况下未编入索引,此处不应应用 500 最大长度)
      • 我在这里找到了关于 TextProperty 的最后评论的答案:stackoverflow.com/questions/3434090/… 您基本上需要在使用 bulkloader 导入时使用 db.Text 来转换字符串,以确保它被保存为文本属性
      猜你喜欢
      • 2014-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-02
      • 2011-04-18
      • 1970-01-01
      相关资源
      最近更新 更多