Google App Engine中的KindError
我在GAE(谷歌应用引擎)里定义了一个简单的类,用来保存用户资料数据,代码大概是这样的:
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
的值。当我尝试用这个cookie获取用户信息时,代码是这样的:
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'
我知道这个用户是存在的,memcache也存在。用户类在我的项目中只定义了一次。为什么会出现这个错误,我该怎么解决呢?
更新:我尝试用 db.get()
替代 User.get()
,结果成功了。那么,这里可能是什么问题呢?
3 个回答
我觉得这个问题比看起来要复杂一些。我在调用 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 是在本地定义的:class GDSDatastore(gds.Model))
Model.get()
会检查你提供的键是否是正确的类型,这个类型在文档中有说明。如果类型不对,它会抛出一个 KindError
错误。
db.get()
则不进行任何类型检查,所以只要你提供的值在数据存储中存在,它就会成功返回,但不一定会返回一个用户实体。
因此,你需要检查一下你在内存缓存中的键是否真的是 User
类型。你确定它没有在某个时候被其他模型的键覆盖吗?
App Engine框架里有一个叫做'User'的类,这是用户API的一部分。而你自己也定义了一个同样名字的类。当出现错误时,你可能在使用一个类,却不小心用了另一个。
为了避免这种情况,建议你给自己的模型换个名字。同时,在Python中导入模块时也要小心。不要这样做:
from google.appengine.api.users import User
或者更糟糕的是:
from google.appengine.api.users import *
你应该这样做:
from google.appengine.api import users
然后你可以用users.User
来引用,这样就不会搞混了。