5

In the GQL reference, it is encouraged to use the IN keyword with a list of values, and to construct a Key from hand the GQL query

SELECT * FROM MyModel WHERE __key__ = KEY('MyModel', 'my_model_key')

will succeed. However, using the code you would expect to work:

SELECT * FROM MyModel WHERE __key__ IN (KEY('MyModel', 'my_model_key1'),
                                        KEY('MyModel', 'my_model_key2'))

in the Datastore Viewer, there is a complaint of "Invalid GQL query string."

What is the correct way to format such a query?

UPDATE: This is not possible to do with the current SDK. As I note in my comment, when using a list, only a reference (e.g. :1 or :email) or an int, float, string, boolean or null literal are acceptable list entries.

SECOND UPDATE: I fixed the bug and it is now possible to perform such queries. Fix can be found in Google Code Hosting diff.

PS I know there are more efficient ways to do this in Python (without constructing a GQL query) and using the remote_api, but each call to the remote_api counts against quota. In an environment where quota is not (necessarily) free, quick and dirty queries are very helpful.

bossylobster
  • 9,993
  • 1
  • 42
  • 61
  • Do you really think that the number of entities you fetch by hand in the console is going to add to a significant amount of consumed quota if you did it via remote_api? – Nick Johnson Dec 09 '11 at 19:15
  • No. Again, I'm just wondering how to structure the query correctly. The second snippet in my post looks like it would not be an "Invalid GQL query string". Is it the case that `WHERE __key__ IN` is invalid GQL? – bossylobster Dec 09 '11 at 19:45
  • I'm still confused why you want to do this, though. It's a particularly inefficient way to fetch entities. – Nick Johnson Dec 09 '11 at 19:58
  • It was really a proof of concept, nothing more. I guess we can agree to let the question die due to lack of practicality. – bossylobster Dec 09 '11 at 20:24
  • This would be useful to me when debugging from the Data Viewer in the admin console. – Chris Dutrow Jan 01 '12 at 06:11
  • OK I finally tracked down the issue. When a list is used, the values in the list are parsed using the `__GetValueList` method which only uses the `__Reference` [method](http://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/ext/gql/__init__.py#1125) and `__Literal` [method](http://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/ext/gql/__init__.py#1147) from the `GQL` class to parse objects. I'm looking into why `=` works with a KEY (without a reference or literal) and possibly submitting a patch. – bossylobster Jan 02 '12 at 21:16

2 Answers2

2

I don't understand. Your objective is to view a specific list of entities in the Datastore Viewer to avoid consuming quota? I don't know of a way to do this with GQL, but you can access entities directly if you know their key, e.g.:

https://appengine.google.com/datastore/edit?app_id=myapp&key=key1

https://appengine.google.com/datastore/edit?app_id=myapp&key=key2

If you're doing this in code, please don't try use GQL. Use db.get(keys) or something similar.

Drew Sears
  • 12,812
  • 1
  • 32
  • 41
  • I have no issues using `db.get` or `MyModel.get_by_key_name` or `MyModel.get_by_id`. The question was fueled by the desire to know how it could be done. Even doing individual queries (as with `key=` in the query string) can be accomplished with `SELECT * FROM MyModel WHERE __key__ = KEY('MyModel', 'my_model_key')`, as I mentioned. – bossylobster Nov 29 '11 at 03:52
1

After the fix was implemented, the code snippet from the original post will suffice:

SELECT * FROM MyModel WHERE __key__ IN (KEY('MyModel', 'my_model_key1'),
                                        KEY('MyModel', 'my_model_key2'))

PS I realized my comment on the original post may not be sufficiently clear as an answer to future viewers.

bossylobster
  • 9,993
  • 1
  • 42
  • 61