GQL é uma linguagem semelhante a SQL para recuperar entidades e chaves. A sintaxe das consultas GQL é parecida com a das SQL. Esta página é uma referência sobre o uso de GQL com as bibliotecas de cliente NDB e DB do Python.
O GQL mapeia aproximadamente para SQL: considere um kind
do GQL como uma tabela SQL, um entity
do GQL como uma linha SQL e um property
do GQL como uma coluna SQL. No entanto, uma pesquisa de coluna/linha SQL é um valor único, e em GQL um valor de propriedade pode ser uma lista.
Versões de GQL
Você precisa de versões diferentes de GQL, dependendo de onde executa consultas. Há duas referências de GQL:
-
Referência sobre GQL para NDB/DB do Python, para a gramática GQL usada nas bibliotecas de cliente NDB e DB (use a referência nesta página).
- Referência sobre GQL para a gramática de GQL usada na atual API Datastore e no leitor de armazenamento de dados do Console do Google Cloud.
Sintaxe
A sintaxe GQL para NDB/DB do Python pode ser resumida assim:
SELECT [DISTINCT] [* | <property list> | __key__] [FROM <kind>] [WHERE <condition> [AND <condition> ...]] [ORDER BY <property> [ASC | DESC] [, <property> [ASC | DESC] ...]] [LIMIT [<offset>,]<count>] [OFFSET <offset>] <property list> := <property> [, <property> ...] <condition> := <property> {< | <= | > | >= | = | != } <value> <condition> := <property> IN <list> <condition> := ANCESTOR IS <entity or key> <list> := (<value> [, <value> ...]])
Assim como acontece com SQL, as palavras-chave GQL são indiferentes a maiúsculas. Os nomes de propriedade e tipo diferenciam maiúsculas e minúsculas.
O GQL aceita apenas instruções SELECT
.
Uma consulta GQL retorna zero ou mais entidades inteiras, entidades projetadas ou chaves do tipo solicitado. Toda consulta GQL sempre começa com SELECT *
, SELECT __key__
ou SELECT <property list>, em que property é uma lista delimitada por vírgulas de uma ou mais propriedades de entidade a serem retornadas da consulta. Uma consulta GQL não executa uma consulta "join" semelhante às de SQL.
Dica: as consultas SELECT __key__ or SELECT
<property list>
são mais rápidas e usam menos tempo de CPU do que as consultas SELECT *
.
A cláusula DISTINCT
(experimental) opcional especifica que apenas resultados totalmente exclusivos serão retornados em um conjunto de resultados. Ela só retornará o primeiro resultado de entidades com os mesmos valores das propriedades sendo projetadas.
A cláusula FROM
opcional limita o conjunto de resultados às entidades do tipo indicado. Uma consulta sem uma cláusula FROM
é chamada de consulta sem tipo e tem apenas um WHERE
que especifica uma propriedade __key__
.
A cláusula WHERE
opcional limita o conjunto de resultados às entidades que atendam a uma ou mais condições. Cada condição compara uma propriedade da entidade com um valor usando um operador de comparação. Se forem dadas várias condições com a palavra-chave AND
, será necessário que uma entidade atenda a todas as condições a serem retornadas pela consulta. O GQL não tem um operador OR
. No entanto, tem um operador IN
, que dá uma forma limitada de OR
.
O operador IN
compara o valor de uma propriedade com todos os itens de uma lista. O operador IN
equivale a muitas consultas =
, uma para cada valor, que são combinadas com o OR. É possível que uma entidade com valor da propriedade indicada igual a qualquer um dos valores da lista seja retornada para a consulta.
Observação: os operadores IN
e !=
utilizam diversas consultas nos bastidores. Por exemplo, o operador IN
executa uma consulta subjacente ao armazenamento de dados separada para cada item da lista. As entidades retornadas são resultado de vários produtos de todas as consultas subjacentes ao armazenamento de dados. A duplicação dessas entidades é eliminada. Um máximo de 30 consultas ao armazenamento de dados é permitido para qualquer consulta GQL única.
Uma condição também testa se uma entidade tem uma determinada entidade como ancestral, utilizando o operador ANCESTOR IS
. O valor é uma instância de modelo ou uma chave da entidade do ancestral. Para mais informações sobre ancestrais, consulte Chaves e grupos de entidades.
O lado esquerdo de uma comparação é sempre o nome de uma propriedade. Normalmente, o nome de uma propriedade consiste em caracteres alfanuméricos, que podem ser combinados com sublinhados e pontos. Em outras palavras, eles correspondem à expressão regular [a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*
.
Cuidado: é necessário usar aspas duplas em nomes de propriedade que contenham outros caracteres imprimíveis. Por exemplo: "first-name"
. Espaços ou caracteres não imprimíveis em nomes de propriedade não são compatíveis.
O lado direito de uma comparação pode ser um dos itens a seguir (conforme for apropriado para o tipo de dados da propriedade):
- Um literal
str
, como uma string entre aspas simples. É necessário usar o escape''
nos caracteres entre aspas simples na string. Por exemplo:'Joe''s Diner'
. - Um literal de número inteiro ou com ponto flutuante. Por exemplo:
42.7
. - Um literal booleano, como
TRUE
ouFALSE
. - O literal
NULL
, que representa o valor nulo (None
no Python). - Um literal de data e hora, de data ou de hora, com valores numéricos ou representação de string, nas seguintes formas:
DATETIME(year, month, day, hour, minute, second)
DATETIME('YYYY-MM-DD HH:MM:SS')
DATE(year, month, day)
DATE('YYYY-MM-DD')
TIME(hour, minute, second)
TIME('HH:MM:SS')
- Um literal de chave de entidade, com uma chave codificada por string ou um caminho completo de IDs/nomes de tipos e chaves:
KEY('encoded key')
KEY('kind', 'name'/ID [, 'kind', 'name'/ID...])
- Um literal de objeto User, com o endereço de e-mail do usuário:
USER('email-address')
- Um literal de GeoPt, com latitude e longitude como valores de ponto flutuante:
GEOPT(lat, long)
- Um valor de parâmetro vinculado. Na string de consulta, os parâmetros posicionais são referenciados por número:
title = :1
. Os parâmetros de palavra-chave são referenciados por nome:title = :mytitle
.
Observação: as condições do formato property = NULL
verificam se um valor nulo está armazenado explicitamente no armazenamento de dados dessa propriedade.
Isso não é o mesmo que verificar se a entidade não tem algum valor da propriedade.
As consultas de armazenamento de dados que se referem a uma propriedade jamais retornam entidades que não tenham um valor dessa propriedade.
É possível vincular os parâmetros como argumentos posicionais ou de palavra-chave transmitidos para o construtor GqlQuery ou para um método gql() da classe de modelo. Os tipos de dados de propriedade que não tenham sintaxe literal de valor correspondente precisam ser especificados usando a vinculação de parâmetro, inclusive o tipo de dado da lista. As vinculações de parâmetros podem ser vinculadas outra vez com novos valores durante o ciclo de vida da instância GqlQuery (como para reutilizar uma consulta com eficiência) usando o método bind().
A cláusula opcional ORDER BY
indica que os resultados serão retornados classificados conforme as propriedades fornecidas, em ordem crescente (ASC
) ou decrescente (DESC
). A cláusula ORDER BY
especifica diversas ordens de classificação como uma lista delimitada por vírgulas, avaliada da esquerda para a direita. Se a direção não for especificada, o padrão será ASC
. Se nenhuma cláusula ORDER BY
for especificada, a ordem dos resultados será indefinida e mudará ao longo do tempo.
Uma cláusula LIMIT
opcional faz a consulta parar de retornar resultados após as primeiras entidades <count>
. A cláusula LIMIT
também inclui um <offset>
para ignorar muitos desses resultados e encontrar o primeiro a retornar. Uma cláusula OFFSET
opcional especifica um <offset>
, se não houver uma cláusula LIMIT
.
Observação: como o parâmetro offset
para o método fetch(), um OFFSET
em uma string de consulta GQL não reduz o número de entidades buscadas no armazenamento de dados. Isso só afeta quais resultados serão retornados pelo método fetch(). Uma consulta com um deslocamento tem características de desempenho correspondentes de maneira linear ao tamanho do deslocamento mais o tamanho limite.
Para informações sobre como executar consultas GQL, vincular parâmetros e acessar resultados, consulte a classe GqlQuery e o método de classe Model.gql().
Exemplos
from google.appengine.ext import db class Person(db.Model): name = db.StringProperty() age = db.IntegerProperty() # We use a unique username for the Entity's key. amy = Person(key_name='amym', name='Amy', age=48) amy.put() Person(key_name='bettyd', name='Betty', age=42).put() Person(key_name='charliec', name='Charlie', age=32).put() Person(key_name='charliek', name='Charlie', age=29).put() Person(key_name='eedna', name='Edna', age=20).put() Person(key_name='fredm', name='Fred', age=16, parent=amy).put() Person(key_name='georgemichael', name='George').put()
Para encontrar todas as entidades do tipo Person
com idades entre 18 e 35 anos (ou seja, os dois Charlies e a Edna), use esta consulta:
SELECT * FROM Person WHERE age >= 18 AND age <= 35
Para encontrar as três entidades do tipo Person
que têm as idades mais altas (ou seja, Amy, Betty e Charlie), use esta consulta:
SELECT * FROM Person ORDER BY age DESC LIMIT 3
Para encontrar as entidades do tipo Person
que têm os nomes "Betty" ou "Charlie", use esta consulta:
SELECT * FROM Person WHERE name IN ('Betty', 'Charlie')
Para retornar apenas os valores name
de cada Person
, use esta consulta:
SELECT name FROM Person
Para retornar apenas os valores name
de cada Person
, ordenados por age
, use esta consulta:
SELECT name FROM Person ORDER BY age
Para encontrar as chaves das entidades do tipo Person
com idade de None
(ou seja, KEY('Person', 'georgemichael')
), use esta consulta:
SELECT __key__ FROM Person WHERE age = NULL
Para encontrar todas as entidades, independentemente do tipo, que estejam no grupo de entidades da Amy (ou seja, Amy e Fred), use esta consulta:
SELECT * WHERE __key__ HAS ANCESTOR KEY(Person, 'Amy')
Para fazer a correspondência por chave, use __key__
no lado esquerdo de uma condição.
Por exemplo, é possível usar isso para receber todas as entidades Person
que tenham um nome de usuário que comece com "a".
SELECT * FROM Person WHERE __key__ >= KEY('Person', 'a') AND __key__ < KEY('Person', 'b')
Observação: se você criar uma consulta com uma igualdade em __key__
, use get()
para buscar a entidade diretamente.