GAE Python2.7 Flask项目调用db.get()获取Datastore实体遇KindError
问题本质
你碰到的这个问题,核心是GAE旧版db API的kind映射机制导致的:当你定义db.Model子类时,框架会自动把类的__name__作为kind注册到内部的_kind_map里。而你事后修改Animal.__name__ = 'common_animal',只是改变了类的名称属性,但已经注册到_kind_map里的映射不会自动更新——所以_kind_map里还是'Animal'对应Animal类,而Datastore里的实体kind是'common_animal',db.get()解析key时找不到对应类,就抛出了KindError。
之前Kay框架能正常工作,是因为Kay内部帮你做了自动映射:它根据appname_classname的规则生成kind,并把这个kind和对应的模型类绑定到_kind_map里,所以db.get()能正确识别。
两种可行的解决方案
1. 定义模型类时指定__kind__属性(推荐)
这是GAE db API官方支持的自定义kind方式,直接在Animal类定义时添加__kind__属性,指定为Datastore里的kind名称:
from google.appengine.ext import db class Animal(db.Model): # 直接指定对应的Datastore kind __kind__ = 'common_animal' # 下面是你的实体属性示例 name = db.StringProperty(required=True) age = db.IntegerProperty() # ...其他属性
当这个类被加载时,框架会自动把'common_animal'这个kind映射到Animal类,_kind_map里的键就会是'common_animal',不管是Animal.all()查询还是db.get()获取实体都能正常工作。
2. 手动更新_kind_map(仅限特殊场景)
如果因为某些限制无法修改Animal类的定义,可以手动修改内部的_kind_map来修正映射:
from google.appengine.ext.db import _kind_map # 先移除原来的错误映射(如果存在) if 'Animal' in _kind_map: del _kind_map['Animal'] # 添加正确的kind与类的映射 _kind_map['common_animal'] = Animal
⚠️ 注意:_kind_map是GAE db API的内部私有变量,这种方式属于临时hack,不推荐长期使用,后续环境变更可能引发问题。
验证是否生效
修改完成后,你可以打印_kind_map来确认映射是否正确:
from google.appengine.ext.db import _kind_map print(_kind_map.get('common_animal')) # 正常情况下会输出类似 <class 'your_app.models.Animal'> 的结果
这时候再调用db.get(str(animal.key()))就不会再触发KindError了。
内容的提问来源于stack exchange,提问作者steve

