Это может быть сложно, если вы переименовали основные ключи для своих свойств ... что некоторые люди предпочитают делать вместо массовых изменений данных
скажем, вы начали с этого:
class Person(ndb.Model):
fname = ndb.StringProperty()
lname = ndb.StringProperty()
тогда однажды вы действительно решили, что было бы лучше использовать first_name и last_name ... так что вы делаете это:
class Person(ndb.Model):
first_name = ndb.StringProperty(name="fname")
last_name = ndb.StringProperty(name="lname")
теперь, когда вы выполняете Person._properties (или .properties () или person_instance._properties), вы получите словарь с ключами, которые соответствуют базовым именам (fname и lname) ... но не будут соответствовать фактическим именам свойств в классе ... так что это не сработает, если вы поместите их в конструктор нового экземпляра или используете метод .populate () (вышеприведенные примеры сломаются)
В любом случае, в NDB экземпляры моделей имеют ._ values словарь, который основан на именах базовых свойств ... и вы можете обновить его напрямую. Я закончил что-то вроде этого:
def clone(entity, **extra_args):
klass = entity.__class__
clone = klass(**extra_args)
original_values = dict((k,v) for k,v in entity._values.iteritems() if k not in clone._values)
clone._values.update(original_values)
return clone
Это на самом деле не самый безопасный способ ... поскольку есть другие частные вспомогательные методы, которые выполняют больше работы (например, проверка и преобразование вычисляемых свойств с использованием _store_value () и _retrieve_value ( ) ) ... но если вы модели достаточно просты, и вам нравится жить на грани :))