2013-03-01 33 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