views:

567

answers:

2

I've run into a strange problem that I haven't seen before making a get_by_key_name call using the App Engine ORM.

Under no circumstances, one would assume, would the following return None:

Model.get_by_key_name(Model.all().get().key().name())

And yet, that's what I've found that certain key names will do. It's only in a few cases where I'm using Open ID URLs like the following as key_name attributes:

https://me.yahoo.com/a/jadjuh3s0klsghiLhtBNbIiHw8k-#3dcl3

(I've changed a couple of chars to protect the innocent)

Maybe the '#' symbol?

Solution: As Nick Johnson suggested, I needed to modify the query since the entity has a parent:

entity = Model.all().get()
Model.get_by_key_name(entity.key().name(), parent=entity.parent_key())

Whatever the case may be, if there is a circumstance where a key name can't be used to fetch an entity, then it shouldn't be allowed to be used as a key name in the first place.

A: 

hi! out of curiosity, do you see this in production, or in the sdk, or both?

i tried to reproduce it with your example key name in http://shell.appspot.com/ , but couldn't:

>>> class Foo(db.Expando):
  pass
>>> Foo(key_name='https://me.yahoo.com/a/jadjuh3s0klsghiLhtBNbIiHw8k-#3dcl3').put()
datastore_types.Key.from_path(u'Foo', u'https://me.yahoo.com/a/jadjuh3s0klsghiLhtBNbIiHw8k-#3dcl3', _app_id_namespace=u'shell')
>>> Foo.get_by_key_name('https://me.yahoo.com/a/jadjuh3s0klsghiLhtBNbIiHw8k-#3dcl3')
<__main__.Foo object at 0x75f9c1aa9181d78>

(granted, i'm not using your model class hierarchy, which you implied might be what's triggering it.)

ryan
This doesn't ordinarily happen. It's very weird that it's only happening with one model, and as I said, there's nothing distinct about how I'm implementing this model. It only inherits from a db.Model subclass that has some utility methods...and that's never caused a problem before.I'll test it out on production and update again soon.
jamtoday
On production it behaves the exact same way, working with all models except for this one specific model, and only with entities that I've recently created. The model is called "Pledge", but that really shouldn't make a difference I'd assume.
jamtoday
And to be clear once again, I've discovered that this behavior occurs regardless of what key name I'm using.
jamtoday
+2  A: 

Model.get_by_key_name(Model.all().get().key().name()) will fail iff the entity returned by the query is a child entity of some other entity. get_by_key_name without a parent parameter looks for an entity with no parents, while the query can return a child entity.

For example:

a = Model1()
a.put()
b = Model2(parent=a)
b.put()
Model2.get_by_key_name(Model2.all().get().key().name()) # Fails to return anything
Model2.get(Model2.all().get().key()) # Works as expected
Nick Johnson
This solved it. And now that I look at the docs again, it's right there. Thanks for the help. Hopefully this answer will help other people who run into this issue.
jamtoday