Uri
Uri

Reputation: 26966

Deleting a child class of polymodel in python appengine

In python appengine, I have a polymodel class (e.g. Animal). I stored in the datastore some instances of child classes (e.g. Horse).

If I delete the definition of the Horse class in the python source code (or change its name), and get the stored Horse entities using db.get and the entity key, what will happen?

e.g. would the retrieved entity be of type Animal? PolyModel? Would there be an exception?

Upvotes: 0

Views: 52

Answers (1)

Dan Cornilescu
Dan Cornilescu

Reputation: 39814

The datastore itself doesn't really know/care about the python class or the data model itself, those are really just implementation details specific to the GAE db or ndb client libraries. You can see that in the Creating an entity example (which uses a generic python client library, without a model definition) - the entity data is simple a dictionary with name-value pairs:

task = datastore.Entity(client.key('Task'))
task.update({
    'category': 'Personal',
    'done': False,
    'priority': 4,
    'description': 'Learn Cloud Datastore'
})

Renaming/deleting the entity model in your application won't delete the entities in the datastore, you'll still be able to see them in the datastore browser.

The key of an already created entity has the entity kind (as a string) embedded in it. Attempting to perform a db.get() on that saved key will raise an KindError exception because it performs a check on the data returned from the datastore against the imported models:

Traceback (most recent call last):
  File "/usr/local/google_appengine/google/appengine/tools/devappserver2/python/request_handler.py", line 226, in handle_interactive_request
    exec(compiled_code, self._command_globals)
  File "<string>", line 12, in <module>
  File "/usr/local/google_appengine/google/appengine/ext/db/__init__.py", line 1540, in get
    return get_async(keys, **kwargs).get_result()
  File "/usr/local/google_appengine/google/appengine/api/apiproxy_stub_map.py", line 613, in get_result
    return self.__get_result_hook(self)
  File "/usr/local/google_appengine/google/appengine/datastore/datastore_rpc.py", line 1715, in __get_hook
    entities = extra_hook(entities)
  File "/usr/local/google_appengine/google/appengine/api/datastore.py", line 643, in local_extra_hook
    return extra_hook(result)
  File "/usr/local/google_appengine/google/appengine/ext/db/__init__.py", line 1509, in extra_hook
    cls1 = class_for_kind(entity.kind())
  File "/usr/local/google_appengine/google/appengine/ext/db/__init__.py", line 299, in class_for_kind
    raise KindError('No implementation for kind \'%s\'' % kind)
KindError: No implementation for kind 'Horse'

So if you want to perform a rework of your models and re-use the already stored data you should keep the old models around to be able to read the data and write it back under the new models.

Upvotes: 2

Related Questions