2013-03-01 58 views
3

我正在使用批量加载器将数据上传到我的App Engine数据存储中。将字典导入App Engine ndb.JsonProperty with bulkloader

我似乎无法储存字典成JsonProperty,我收到以下错误:

BadValueError: Unsupported type for property nearby_countries: <type 'dict'>

我的模型定义了这个属性作为JsonProperty:

nearby_countries = ndb.JsonProperty()

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

我对JsonProperty的理解是,它需要一个python对象作为值,我不应该对ndb将处理的JSON序列化感到困扰。我对么?

Value is a Python object (such as a list or a dict or a string) that is serializable using Python's json module; the Datastore stores the JSON serialization as a blob.

回答

3

经过大量尝试&误差以及周围的Googling类似的帖子,我设法找到了下面的帖子引来了我下面的解决方案:

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

总之,JsonProperties存储为斑点我们需要传递bulkloader正确的转换方法来从json字符串中生成一个blob。我们可以用transform.blobproperty_from_base64(从google.appengine.ext.bulkload.transform模块)

所以我将我的列表或字典的字符串JSON字符串表示然后把它转换成一个BLOB,以便bulkloader可以存储它:

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)

+1

它可以接受你自己的答案,你知道的! – 2013-03-01 16:40:47

1

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

+0

感谢。问题是,当我打电话json.dumps()自己,字符串获取存储在数据存储,而不是一个blob。我可以在管理控制台中看到存储的值呃属性被定义为JsonProperty,这应该导致二进制被存储。稍后加载此属性时,它会抱怨它不是JSON对象。 – Erwan 2013-03-01 01:39:36

+0

我实际上认为它可能与bulkloader验证有关。任何人都知道在哪里可以找到它,我会尝试看看我们是否可以losen它来确保我的在JsonProperty被接受。 我发现唯一的其他解决方法是首先通过批量加载器将字符串导入到TextProperty中,然后运行一个脚本,该脚本将从字符串中创建并将其存储到JsonProperty中。虽然不是最优的。 – Erwan 2013-03-01 02:04:34

+0

散装加载器的验证肯定存在问题。我也收到以下错误: 物业XXXX太长。最大长度为500 对于XXXX声明为TextProperty(默认情况下不与500最大长度索引不应该在这里适用)属性 – Erwan 2013-03-01 03:32:36