Может ли ndb.KeyProperty ссылаться на базовый класс модели при использовании наследования модели?

У меня есть несколько моделей с общим набором свойств, которые я определил в классе базовой модели, от которого наследуются другие модели:

class BaseUser(ndb.Model):
    name = ndb.StringProperty()

class DerivedUserA(BaseUser):
    # some additional properties...

class DerivedUserB(BaseUser):
    # some additional properties...

В какой-то другой модели мне нужна ссылка на любую модель, производную от BaseUser:

class MainModel(ndb.Model):
    user = ndb.KeyProperty(kind = BaseUser)

Однако, когда я пытаюсь установить ключ объекта DerivedUserA для свойства MainModel.user, GAE выдает BadValueError, заявляя, что он ожидает ключ с типом BaseUser, но получил DerivedUserA.

Если я удалю аргумент kind из своего MainModel, он сработает:

class MainModel(ndb.Model):
    user = ndb.KeyProperty()

Я мог бы с этим смириться, но я бы предпочел иметь проверку, чтобы убедиться, что я не пытаюсь сохранить какую-либо сущность в свойстве MainModel.user. Есть ли способ сделать это?


person Pascal Bourque    schedule 15.08.2012    source источник


Ответы (2)


Используйте PolyModel для наследования хранилища данных -> https://developers.google.com/appengine/docs/python/ndb/polymodelclass

person Gwyn Howell    schedule 15.08.2012
comment
Ничего себе, даже проведя последние 2 дня, погруженные в документацию ndb, этот класс каким-то образом остался незамеченным. Большое спасибо! - person Pascal Bourque; 16.08.2012

Причина, по которой это не работает, заключается в том, что параметр kind для KeyProperty() немедленно преобразуется в строку.
Поскольку это всего лишь функция проверки, мы могли бы рассмотреть возможность исправления этого.
Если вам нравится эта идея, вы можете отправить запрос функции в трекере: http://code.google.com/p/appengine-ndb-experiment/issues/list - это будет менее тяжеловесно, чем PolyModel (хотя кажется, что PolyModel может быть тем, что вы ищете в любом случае).

person Guido van Rossum    schedule 15.08.2012
comment
Спасибо! Действительно, PolyModel — это то, что мне нужно, потому что он решает другую проблему, которая у меня была с моим первоначальным наследованием модели, а именно то, что я не мог выполнить запрос среди всех объектов, производных от BaseUser (поскольку они хранились в разных таблицах хранилища данных). Я не думаю, что прошу вас исправить это в KeyProperty, поскольку кажется, что PolyModel действительно является способом правильного наследования модели. - person Pascal Bourque; 16.08.2012