Skip to content

Instantly share code, notes, and snippets.

@marcia
Created September 25, 2013 05:33
Show Gist options
  • Save marcia/6695509 to your computer and use it in GitHub Desktop.
Save marcia/6695509 to your computer and use it in GitHub Desktop.
how does a db object reference an ndb object in app engine?
class NdbKeyProperty(db.Property):
"""Stores an ndb key in a db model."""
def get_value_for_datastore(self, model_instance):
value = super(NdbKeyProperty, self).get_value_for_datastore(
model_instance)
if value is None:
return value
# We were given an ndb key, and we want to store it as a db key
return value.to_old_key()
def make_value_from_datastore(self, value):
if value is None:
return None
# From the db key, turn it into an ndb key
return ndb.Key.from_old_key(value)
class _TargetModelNdb(ndb.Model):
# A vanilla ndb model
value = ndb.StringProperty(default='')
class _LinkByNdbKeyModel(db.Model):
# A db model, that links to an ndb model via NdbKeyProperty
target = NdbKeyProperty(indexed=True, default=None)
class NdbKeyPropertyTest(gae_model.GAEModelTestCase):
def test_reading_default_value_returns_none(self):
link = _LinkByNdbKeyModel()
# This works
self.assertIsNone(link.target)
def test_reading_property_value_returns_an_ndb_key(self):
target = _TargetModelNdb(value="test")
target.put()
link = _LinkByNdbKeyModel()
link.target = target.key
link.put()
# These work
self.assertIsInstance(link.target, ndb.Key)
self.assertEqual(target.key, link.target)
# Below will fail, as db queries get confused by the ndb key being passed in
result = _LinkByNdbKeyModel.all().filter("target =", target.key).get()
# This is confusing because the opposite works.
# (In other words, you can have an ndb object reference a db object, and filter by db key.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment