0

It looks like KeyProperty's kind validation doesn't work for subclass of PolyModel.

from google.appengine.ext import ndb
from google.appengine.ext.ndb import polymodel


class Item(polymodel.PolyModel):
    parent = ndb.KeyProperty(kind="Folder")

class Folder(Item):
    title = ndb.StringProperty()

    def add_item(self, item):
        item.set_parent(self.key)

class File(Item):
    pass


class Main(webapp2.RequestHandler):
    def get(self):
        rootfolder = Folder(title="root")
        rootfolder.put()

        # the next line raise exception
        subfolder = Folder(title="Cool things", parent=rootfolder.key) 
        subfolder.put()

Exception:

line 1935, in _validate
    'Expected Key with kind=%r, got %r' % (self._kind, value))
BadValueError: Expected Key with kind='Folder', got Key('Item', 6544293208522752)

looks like the same thing as Guido van Rossum said in Can ndb.KeyProperty reference a base model class when using model inheritance?

Community
  • 1
  • 1
lucemia
  • 6,349
  • 5
  • 42
  • 75

1 Answers1

1

It's actually working as expected.

You can only have parent = ndb.KeyProperty(kind="Item") as the kind of Folder as stored in the datastore is Item.

It has additional properties that define it's inheritance heriarchy and allows you to perform queries like Item.query() and get all subclasses of Item.

Have another read of PolyModel docs and have a look at the entities as stored in the datastore, then everything will be clear.

Tim Hoffman
  • 12,976
  • 1
  • 17
  • 29
  • I think the `kind` is for validation only, so how it stored in the datastore should be the problem? – lucemia Apr 05 '14 at 06:51
  • 1
    Except validation is performed during a put. At that point you will probably find that the internal transformation of the PolyModel has already ocurred. Also have a look at the code and see what it is actually validating. If you want to restrict the property to a `Folder` then write your own validation function. – Tim Hoffman Apr 05 '14 at 07:10
  • 1
    Also revisit the validation error. The `Key` is being validated not the class and the `Key` of a `Folder` object based on your classes is `Key('Item', 6544293208522752)` and from the `Key` we can see the kind is `Item` not `Folder`. – Tim Hoffman Apr 05 '14 at 07:30