9
votes

This is about Google App Engine's ndb. According to my observations, if I create an entity without providing any key, the entity will have an integer, starting with 1 and being incremental, in the ID field as shown in Datastore Viewer. However, if I create the entity by providing with a string as its id, the entity will have a string in the Key Name field. For example:

Model:

class Member(ndb.Model):
  ...

program:

member1 = Member()            # --> ID is 1, Key Name is None
member2 = Member(id='abc')    # --> ID is empty, Key Name is 'abc'

In addition, in the html file, if I use

<input ... name="id" value={{member1.key.id}} ... />

as a parameter to return to the server-side program (Python), none of the following two statements will work for member1:

Member.get_by_id(self.request.get('id'))
member1 = Member.get_by_id(int(self.request.get('id')))

However, the following html and program codes:

<input ... name="id" value={{member2.key.id}} ... />
member2 = Member.get_by_id(self.request.get('id'))

will work for member2.

There seems no problem for entities created by providing with string id's (i.e., member2). But the same doesn't work for member1. My questions: a) Are my observations correct? b) How do I fetch member1 using get_by_id()?

1
Have you fetched all Members and examined their keys so that you know 1. that you have in fact written member1 and member2 ? andTim Hoffman
2. what keys you have actually createdTim Hoffman

1 Answers

13
votes

a) Mostly correct, though you should be able to get member1 through the second method you showed. Also can't verify that integer IDs always start at 1 and will always be incremental. I've seen mixed results in regards to that.

b) member1 = Member.get_by_id(int(self.request.get('id'))) should work

You could also try using key.urlsafe() so you dont have to worry about key id conversions:

<input ... name="id" value={{member.key.urlsafe()}} ... />

member_key = self.request.get('id')
member = ndb.Key(urlsafe=member_key).get()