0

My code is intended to:

  • Retrieve a user_id from a cookie, if it exists.
  • Query the datastore using the user_id to retrieve the user record.
  • Finally, if a record is found, it displays a welcome message. (signup is passed to a template)

I cannot get the app to display the welcome message. As far as I can tell the issue is that the query always returns None. I've verified the cookie and the data in the datastore exists.

What am I doing wrong with this query? Does GQL handle IDs in where clauses in a non-intuitive way?

#Get  cookie        
user_id = self.request.cookies.get("user_id", 0)

#Query Datastore for matching user_id
user = db.GqlQuery("SELECT * FROM User WHERE id = %s" % user_id).get()  

#If a user is found, display the username
if user.username:
    signup = "Welcome, %s" % user.username
Hess
  • 130
  • 4

1 Answers1

1

The datastore has a Key property, which is made up of (optional) ancestors, the kind, and a name or id. However, there is no specific id property. (Reference)

To get an entity with a specific key, your code should look something like this:

# Get cookie        
user_id = self.request.cookies.get("user_id", 0)

if not user_id:
  # handle this case, otherwise the call to from_path will fail.

# Build key
user_key = db.Key.from_path('User', long(user_id))

# Get the entity
user = db.get(user_key)

# If a user is found, display the username
if user.username:
    signup = "Welcome, %s" % user.username

You actually don't want to use a query in this case because you already know the key of the entity you are looking for.

When you are querying with keys, you have to specify the entire key (not just the id):

user = db.GqlQuery("SELECT * FROM User WHERE __key__ > KEY('User', %s)" % user_id).get()

Notice here I am using an inequality, since using an equality filter for a key does not make sense given that you can do a direct lookup. Here is the reference for using KEY in a GQL string and I've quoted the relevant section below:

The right-hand side of a comparison can be one of the following (as appropriate for the property's data type):

  • an entity key literal, with either a string-encoded key or a complete path of kinds and key names/IDs:

    • KEY('encoded key')

    • KEY('kind', 'name'/ID [, 'kind', 'name'/ID...])

Community
  • 1
  • 1
Patrick Costello
  • 3,616
  • 17
  • 22
  • Ok, so I had previously gotten this somewhat working using the get_by_id method user = User.get_by_id(int(user_id)) but was running into an error when the cookie does not exist. Your code also produces this same error. This is due to the default value I use when the user_id cookie does not exist user_id = self.request.cookies.get("user_id", 0). Turns out the from_path() method does not accept 0 for the id_or_name argument. From the Google App Engine documentation: The id, specified as a string or long. It cannot be the number 0. – Hess Oct 08 '13 at 03:11
  • Ah yes you are totally right -- a missing cookie will break it. I'll go ahead and edit the code so other people don't run into the same problem. – Patrick Costello Oct 08 '13 at 21:07