2010-09-23

[筆記]Python中使用pickle時出現KeyError

遇到這個問題是在使用google app engine (GAE)中使用pickle的時候遇到的。

我利用pickle的dumps將一個物件序列化成字串存入GAE的datastore中,需要用時再取出字串用pickle.loads()還原成原本的物件。如下會出現"KeyError: \x00"的錯誤

from google.appengine.ext import db
class TestDB(db.Model):
    serialize_obj=db.TextProperty()

obj={'a':1,'b':'c'} #要存入datastore的物件
t=TestDB(key_name='test') #建立entity

import pickle
t.serialize_obj=pickle.dumps(obj) #將obj序列化成字串 並存到剛建立的entity中
t.put() #寫入datastore

#下面將讀出剛的字串並還原成物件
t2=TestDB.get_by_key_name('test') #讀出剛剛存的entity
obj2=pickle.loads(t2.serialize_obj) #理論上會字串還原為物件 並放到obj2變數中, 但是這裡會出現KeyError錯誤
print obj2 #上面沒錯的話 會print出{'a':1,'b':'c'}

其實這個問題很簡單,問題在於GAE的datastore在處理Text的資料型態,會將其存為unicode。而將unicode丟給pickle.loads就會導致這個問題。 修改上很簡單,最好的作法就是將db.TextProperty()改成db.BlobProperty(),不然也可以將unicode再轉回一般字串pickle.loads(str(t2.serialize_obj)),但是這樣只是多做無謂的轉換...