2011-04-11 150 views
2

我定義在GAE一個簡單的類保持用戶配置文件數據是這樣的:KindError在谷歌應用程序引擎

class User(db.Model): 
    email = db.EmailProperty() 
    role = db.StringProperty(default=roles.USER) 
    first_name = db.StringProperty() 
    last_name = db.StringProperty() 
... 

我使用的memcache保持會話信息。 memcache數據看起來像這樣{ 'key': 'agpjYW5kaXJhdGVzcgoLEgRVc2VyGCMM'}。我從cookie獲取session_id值。當我試圖讓鏈接到餅乾這樣的用戶信息:

session_id = request['session_id'] 
data = memcache.get(session_id) 
user = User.get(data['key']) 

我得到KindError例外:

KindError: Kind 'User' is not a subclass of kind 'User' 

我知道這個用戶是否存在,存在內存緩存。用戶類只在我的項目中定義過一次。爲什麼會發生此錯誤,我該如何使其工作?

更新:我試着用db.get()而不是User.get()它工作。那麼,有什麼問題呢?

回答

0

App Engine框架將一個名爲'User'的類定義爲Users API的一部分。另外,你有相同名字的你自己的班級。發生異常時,您正在嘗試使用其中一個,但獲取另一個。

爲了避免這種情況,請重命名您的模型。您還應該小心如何使用Python導入模塊。相反的:

from google.appengine.api.users import User 

或者更糟:

from google.appengine.api.users import * 

你應該使用:

from google.appengine.api import users 

,然後參考users.User,這是毫不含糊的。

+0

這些是非常有用的說明。我會根據你的建議更新我的代碼。謝謝! – 2011-04-14 09:33:56

1

Model.get()確實檢查提供的密鑰是否是正確的種類,如documentation中所定義。如果不是正確的類型,它會拋出一個KindError

db.get()不會做任何類型檢查,因此如果存在於數據存儲中,將會使用提供的值成功,但不一定會返回用戶實體。

因此您需要檢查您的memcache中的密鑰實際上是否爲User類型。你確定它在某個時刻不會被其他模型的關鍵字覆蓋嗎?

+0

看來這個問題是進口。在不同的模塊中我使用了不同的導入語句一個從lib.utils.profiles中使用的導入用戶,它運行良好,因爲它包含模塊的整個路徑。另一個從utils.profiles中使用導入用戶,它引發了一個異常。 – 2011-04-11 11:51:00

0

這個問題在我看來,比這個更微妙。我得到這個調用Model.get()錯誤(我檢索頂級單對象,總是在那裏):

datastore = GDSDatastore.get(gds.Key.from_path(*path)) 

所以我研究了這個代碼:

datastore = gds.get(gds.Key.from_path(*path)) 
if not(datastore is None or isinstance(datastore, GDSDatastore)): 
    logger.error("KindError isinstance(GDSDatastore)=%s class=%s" % (isinstance(datastore, GDSDatastore), datastore.__class__.__name__)) 
    raise gds.KindError('Kind %r is not a GDSDatastore instance' % 
        (datastore.kind())) 

絕大多數的時候,我沒有錯誤,但今天我得到了這個有趣的日誌:現在

KindError isinstance(GDSDatastore)=False class=GDSDatastore 

,這令我頗爲奇特。

(注:GDSDatastore在本地定義:類GDSDatastore(gds.Model))