4

I'm using get_by_id() to read entities from NDB and I do not get it to work for entities that are part of an entity group:

from google.appengine.ext import ndb

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

parent_folder_key = Folder(name = 'Parent folder').put()    
sub_folder_key = Folder(name = 'Subfolder', parent=parent_folder_key).put() 

id_list = []
print 'All folders:'
for f in Folder.query():
  print f
  id_list.append(f.key.id())

print '\nFolders by id:'
for id in id_list:
  print Folder.get_by_id(id)

Output:

All folders:
Folder(key=Key('Folder', 5814), name=u'Parent folder')
Folder(key=Key('Folder', 5814, 'Folder', 5815), name=u'Subfolder')

Folders by id:
Folder(key=Key('Folder', 5814), name=u'Parent folder')
None

Is by design or is it a bug? I saw that there have been some issues relating to get_by_id() when using namespaces previously (I'm using SDK 1.6.6). How can I folders that have parents from the id?

Community
  • 1
  • 1
Arne S
  • 1,004
  • 14
  • 41

1 Answers1

8

get_by_id(id, parent=None) takes a parent parameter.
when you query by id in an entity group you have to include the parent key to be able to get the entity you want.

https://developers.google.com/appengine/docs/python/ndb/modelclass#Model_get_by_id

aschmid00
  • 7,038
  • 2
  • 47
  • 66
  • 1
    The id is unique even if there is a parent so I do not understand why it should not be possible to get and entity by its id even if here is a parent. – Arne S Jun 15 '12 at 13:16
  • 4
    an id is unique only for that specific entity group. an id is only a the part of a key and which includes also the parent entity. get_by_id will need to reconstruct the full entity key to get the entity. – aschmid00 Jun 15 '12 at 13:20
  • Thank you aschmid00. The way I understand this is that entities without a parents and ancestors form their own entity group. If that is the case the ids need to be unique for the whole model class. Am I mistaken? – Arne S Jun 15 '12 at 13:29
  • 1
    from what i know if you wan't to create an entity with a custom id you will need to construct a whole Key first and use that for the entity. by doing this you already create a specific entity group `Key(kind1, id1)` so whenever you set kind1 in in your Key constructor it will be the same entity group and the id has to be unique. without specifying a parent or key GAE automatically sets the model class as its entity group. you will need to try this out urself because im not completely sure but confident enough that it works that way. – aschmid00 Jun 15 '12 at 13:39
  • 5
    Trust me, the ID is not unique when there is a parent. All the information in the key is necessary to uniquely identify an entity. Hierarchically, this comes down to: app; namespace; toplevel kind; toplevel id; child kind; child id. (If there are multiple levels of ancestors these must all be included.) – Guido van Rossum Jun 15 '12 at 22:44
  • yes that came out wrong from my side. i was thinking about the app im developing. i have a root entity group which consists of a constructed key and multiple kinds belong to that entity group, so when specifying that parent i use that root key. so there the id is unique. – aschmid00 Jun 16 '12 at 00:01
  • This answer (and the truth of it) just saved me a minor conniption as I realized my existing calls to `Model.get_by_id` might fail after I spent a bunch of time implementing ancestry in my data model. LOL. – Tom Russell May 28 '17 at 09:25