Reputation: 21094
Not this question (where the problem is using ANCESTOR =
instead of ANCESTOR IS
)
I used ANCESTOR IS
properly:
SELECT DISTINCT batch_no
FROM Entry
WHERE ANCESTOR IS KEY('ag1kZXZ-dHRiLXRhbWVychkLEgdCcmV3ZXJ5IgxCUi1USEVSRURQRUEM')
But I still got an error:
Identifier is a reserved keyword as symbol ANCESTOR
Why is that?
EDIT
I'm getting the same error later years later as I try to update from db
to ndb
, but I think it's a different reason...
Identifier is a reserved keyword at symbol ANCESTOR
But in this case my query is not using DISTINCT
SELECT *
FROM Balance
WHERE ANCESTOR IS KEY('...')
AND first_balance_ever = TRUE
ORDER BY created_date
So I'm not sure the problem here, maybe it's ANCESTOR
related, maybe it's KEY(...)
related...
Upvotes: 2
Views: 102
Reputation: 21094
I modified my question because I faced this error years later when updating from db
to ndb
.
If only going from db
to ndb
My problem was a GQL Query like this
"ANCESTOR IS KEY('{}')".format(model.key)
Notice the difference was going
model.key()
, which returned a "url safe" encodable string value...model.key
, which stringifies as KEY('Kind', 'id')The result was a this string, which is clearly wrong:
ANCESTOR IS KEY('KEY('Kind', 'id')')
If going from db
or ndb
to the Datastore
I think the problem is described here, and documented here
Python GQL expression
ANCESTOR IS <entity-or-key-value>
is represented in Datastore GQL as the more general expression__key__ HAS ANCESTOR <key-value>
So I think db
is using Python GQL, whereas ndb
might be using Datastore GQL.
Note also:
Python GQL supports queries using a URL-safe (base64-encoded) key. Datastore GQL does not.
...although note that ndb
does have this method...
key = ndb.Key(urlsafe=encoded_key)
The "DB to NDB Client Library Migration" documentation doesn't make it clear how GQL changes... although does imply ndb
keys are different than db
keys:
You can even convert between
ext.db
andNDB
keys usingndb.Key.from_old_key()
andkey.to_old_key()
.
The legacy GQL reference says the Key can be:
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...])
But the Datastore GQL reference says
Upvotes: 0
Reputation: 21094
In this case, DISTINCT
was causing the problem. Remove it and the query works as expected.
I think the query is implicitly projecting only that property you DISTINCT
on, so you cannot access the key/ancestor for ANCESTOR IS
. (But is this true even if you use SELECT *
?)
But the error message is not very clear...
Google describes that DISTINCT
is experimental. Mentions this in db.Query
documentation:
Grouping(experimental)
Projection queries can use the
distinct
keyword to ensure that only completely unique results will be returned in a result set. This will only return the first result for entities which have the same values for the properties that are being projected.
And in the GQL documentation
The optional
DISTINCT
(experimental) clause specifies that only completely unique results will be returned in a result set. This will only return the first result for entities which have the same values for the properties that are being projected.
Upvotes: 2