Search code examples
python-2.7google-app-engineflaskgoogle-cloud-datastoreapp-engine-ndb

GAE: Cloud Datastore KindError when getting entity from key


I have an app running on GAE Python2.7 Standard environment using Datastore.

Our Datastore's entity's kind is currently based on a naming convention of 'appname_classname' (lowercase).

kind
- common_account (under "common" app's Account class)
- common_animal (under "common" apps's Animal class)

This naming convention is due to the feature of framework (kay framework). As long as I am using kay framework, there was no error getting entity like the following.

from google.appengine.ext import db
from common.models import Animal
lst = [e for e in Animal.all()]
animal = lst[0]
db.get(str(animal.key()))

But this time I created a new project based on Flask with existing Datastore's data. So I exported all entities from a current project and imported them to a new project.

And I renamed class using __name__.

from google.appengine.ext import db
class BaseModel(db.Model):
    created_at = db.DateTimeProperty(auto_now_add=True)
    updated_at = db.DateTimeProperty(auto_now=True)
    is_deleted = db.BooleanProperty(default=False)

class Animal(BaseModel):
    name = db.StringProperty()
    number = db.IntegerProperty()

Animal.__name__ == 'common_animal'

I was able to get entities of kind 'common_animal' using query below since I changed name of Animal class to 'common_animal'.

lst = [e for e in Animal.all()]

But when I tried to get entity using db.get(), I get the KindError. Why am I getting KindError even thought I changed Animal class name to 'common_animal.

from google.appengine.ext import db
from common.models import Animal
lst = [e for e in Animal().all().fetch(limit=100)]
animal = lst[0]
db.get(str(animal.key()))
KindError: No implementation for kind 'common_animal'

It looks like the error is comming from 'google-cloud-sdk/platform/google_appengine/google/appengine/ext/db/init.py' 's class_for_kind. _kind_map is not recognizing __name__, which shoule be 'common_animal'

pp _kind_map
{'Animal': <class 'common.models.Animal'>,
 'BaseModel': <class 'common.models.BaseModel'>,
 'Division': <class 'common.models.common_division'>,
 'Expando': <class 'google.appengine.ext.db.Expando'>,
 'Model': <class 'google.appengine.ext.db.Model'>,
 '__BlobMigration__': <class 'google.appengine.ext.blobstore.blobstore.BlobMigrationRecord'>}

Solution

  • You'll want to override the kind() method on the model class instead of setting __name__. The reference docs are at https://cloud.google.com/appengine/docs/standard/python/datastore/modelclass#Class_Methods .

    The NDB transition doc vaguely has an example.