Reputation: 33
Similar to the question asked here:
Set a kind name independently of the model name (App Engine datastore)
but instead for NDB.
My use case is as follows:
We modified our db code to use prefixes for the datastore kind names (e.g. instead of 'Car' it uses ModuleName_Car). We are now upgrading to NDB and don't have a way to change 'Car' to ModuleName_Car, and subsequently ndb is unable to read existing data. Any workarounds that don't involve naming my model 'ModuleName_Car(ndb.Model)' ?
Upvotes: 3
Views: 416
Reputation: 29983
To expand on David's answer
class NdbCredential(ndb.Expando):
...
@classmethod
def _get_kind(cls):
return 'Credential'
does the job.
Upvotes: 1
Reputation: 410
Here's how I approached this problem for the specific use case of mixing db and ndb Models/Keys.
Suppose your db class was defined as:
class CarModel(db.Model):
brand = db.ReferenceProperty(reference_class=Brand)
And db.ReferenceProperty Brand identified itself with brand.kind() == "my_Brand". The corresponding ndb.Model might look like:
class CarModel(ndb.Model):
brand = KeyProperty(kind="my_Brand")
This should solve your issue since myBrand is properly referenced by the kind. In my case, I specifically wanted to mix db.Key into the ndb.Model by assigning the field by the ndb.Key, db.Key, or db.Model and then retrieving a db.Key to be used in query filters and other matching logic. I subclassed ndb.KeyProperty to handle the behavior as follows (code golf/corrections welcome):
class DbReferenceProperty:
@staticmethod
def _db_to_ndb_key(entity):
if entity is None:
return None
ndb_key = ndb.Key.from_old_key(entity) if type(entity) == db.Key else ndb.Key.from_old_key(entity.key())
#Overrides ndb.KeyProperty method
def _validate(self, value):
if not isinstance(value, ndb.Key) and not isinstance(value, db.Key) and not isinstance(value, db.Model):
raise TypeError("Unexpected type: %s" % repr(value))
#Overrides ndb.KeyProperty method
def _to_base_type(self, value):
if isinstance(value, db.Key) or isinstance(value, db.Model):
value = DbReferenceProperty._db_to_ndb_key(value)
return value
#Overrides ndb.KeyProperty method
def _from_base_type(self, value):
prop_id, kind_str = value.id(), value.kind()
db_key = db.Key.from_path(kind_str, prop_id)
return db_key
Upvotes: 0
Reputation: 6587
The NDB Cheat Sheet doc hinted enough (via _get_kind()
) to point me to this section of the documentation:
The kind is normally the name of the model class to which the entity belongs ("Account" in the example above), but can be changed to some other string by overriding the classmethod _get_kind().
Upvotes: 4