Google App Engine中的KindError

2 投票
3 回答
532 浏览
提问于 2025-04-16 15:29

我在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 个回答

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 是在本地定义的:class GDSDatastore(gds.Model))

1

Model.get() 会检查你提供的键是否是正确的类型,这个类型在文档中有说明。如果类型不对,它会抛出一个 KindError 错误。

db.get() 则不进行任何类型检查,所以只要你提供的值在数据存储中存在,它就会成功返回,但不一定会返回一个用户实体。

因此,你需要检查一下你在内存缓存中的键是否真的是 User 类型。你确定它没有在某个时候被其他模型的键覆盖吗?

0

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来引用,这样就不会搞混了。

撰写回答