GQL è un linguaggio di tipo SQL per il recupero di entità e chiavi. La sintassi per le query GQL è simile a quella di SQL. Questa pagina è un riferimento per l'utilizzo di GQL con le librerie client NDB e DB di Python.
GQL è mappato più o meno a SQL: puoi pensare a GQL kind
come a una tabella SQL, a GQL entity
come riga SQL e a property
GQL come colonna SQL. Tuttavia, una ricerca riga-colonna SQL è un singolo valore, mentre in GQL un valore di proprietà può essere un elenco.
Versioni GQL
Sono necessarie versioni diverse di GQL a seconda di dove esegui le query. Esistono due riferimenti GQL:
-
Riferimento GQL per Python NDB/DB, per la grammatica GQL utilizzata nelle librerie client NDB e DB (utilizza il riferimento in questa pagina).
- Riferimento GQL, per la grammatica GQL utilizzata nell'API Datastore attuale e nel visualizzatore Datastore della console Google Cloud.
Sintassi
La sintassi di GQL per Python NDB/DB può essere riassunta come segue:
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> ...]])
Come nel caso di SQL, le parole chiave GQL non fanno distinzione tra maiuscole e minuscole. I nomi di tipo e proprietà sono sensibili alle maiuscole.
GQL supporta solo istruzioni SELECT
.
Una query GQL restituisce zero o più entità intere, entità proiettate o chiavi del tipo richiesto. Ogni query GQL inizia sempre con SELECT *
,
SELECT __key__
o SELECT <property list>, dove
property è un elenco delimitato da virgole di una o più proprietà entità
da restituire dalla query. (Una query GQL non può eseguire una query di
join di tipo SQL).
Suggerimento: le query SELECT __key__ or SELECT
<property list>
sono più veloci e utilizzano meno tempo di CPU
rispetto alle query SELECT *
.
La clausola facoltativa DISTINCT
(sperimentale)
specifica che in un set di risultati verranno restituiti solo risultati completamente univoci. Verrà restituito solo il primo risultato per le entità che hanno gli stessi valori per le proprietà oggetto della previsione.
La clausola facoltativa FROM
limita l'insieme di risultati a queste entità
del tipo specificato. Una query senza una clausola FROM
è chiamata query senza genere e può avere solo un WHERE
che specifica una proprietà __key__
.
La clausola facoltativa WHERE
limita l'insieme di risultati alle
entità che soddisfano una o più condizioni. Ogni condizione confronta una proprietà dell'entità con un valore utilizzando un operatore di confronto. Se con la parola chiave AND
vengono specificate più condizioni, un'entità deve soddisfare tutte le condizioni per essere restituita dalla query. GQL non ha un operatore OR
. Tuttavia, ha un operatore IN
, che fornisce una
forma limitata di OR
.
L'operatore IN
confronta il valore di una proprietà con ogni elemento in un
elenco. L'operatore IN
è equivalente a molte query =
,
una per ogni valore, unite in OR. Per la query può essere restituita un'entità il cui valore per la proprietà specificata corrisponde a uno qualsiasi dei valori nell'elenco.
Nota:gli operatori IN
e !=
utilizzano più query dietro le quinte. Ad esempio, l'operatore IN
esegue una query separata sul datastore sottostante per ogni elemento dell'elenco. Le entità restituite sono il risultato dell'incrocio di prodotti di tutte le query sul datastore sottostanti e sono deduplicate. Sono consentite un massimo di 30 query sul datastore per ogni singola query GQL.
Una condizione può anche verificare se un'entità ha una determinata entità come predecessore, utilizzando l'operatore ANCESTOR IS
. Il valore è un'istanza del modello o una chiave per l'entità predecessore. Per maggiori informazioni sui predecessori, consulta
Chiavi e gruppi di entità.
Il lato sinistro di un confronto è sempre il nome di una proprietà. Il nome di una proprietà tipica è costituito da caratteri alfanumerici, eventualmente combinati con trattini bassi e punti, In altre parole, corrispondono all'espressione regolare [a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*
.
Attenzione: i nomi delle proprietà che contengono altri caratteri stampabili devono essere racchiusi tra virgolette. Ad
esempio: "first-name"
. Gli spazi o i caratteri non stampabili nei nomi delle proprietà non sono supportati.
Il lato destro di un confronto può essere uno dei seguenti (a seconda del tipo di dati della proprietà):
- un valore letterale
str
, come stringa tra virgolette. Le virgolette singole nella stringa devono essere precedute dal carattere di escape''
. Ad esempio:'Joe''s Diner'
- un numero intero o con rappresentazione in virgola mobile. Ad esempio:
42.7
- un valore letterale booleano, come
TRUE
oFALSE
. - il valore letterale
NULL
, che rappresenta il valore nullo (None
in Python). - un valore letterale data/ora, data o ora, con valori numerici o una rappresentazione di stringa, nei seguenti formati:
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')
- un valore letterale di chiave entità, con una
chiave con codifica stringa
o un
percorso completo di tipi e nomi/ID
chiavi:
KEY('encoded key')
KEY('kind', 'name'/ID [, 'kind', 'name'/ID...])
- un valore letterale oggetto utente, con l'indirizzo email dell'utente:
USER('email-address')
- un valore letterale GeoPt con latitudine e longitudine come valori in virgola mobile:
GEOPT(lat, long)
- un valore parametro associato. Nella stringa di query, ai parametri posizionali viene fatto riferimento dal numero:
title = :1
. Ai parametri della parola chiave viene fatto riferimento in base al nome:title = :mytitle
Nota: le condizioni del formato property = NULL
controllano se un valore nullo è archiviato esplicitamente nel datastore per quella proprietà.
Non è la stessa cosa che controllare se nell'entità manca un valore per la proprietà.
Le query Datastore che fanno riferimento a una proprietà non restituiscono mai entità che non hanno un valore per quella proprietà.
I parametri associati possono essere associati come argomenti posizionali o argomenti parola chiave passati al costruttore GqlQuery o al metodo gql() di una classe di modello. I tipi di dati della proprietà che non hanno una sintassi di valore letterale corrispondente devono essere specificati utilizzando l'associazione di parametri, incluso il tipo di dati dell'elenco. Le associazioni di parametri possono essere ricollegate con nuovi valori durante la durata dell'istanza GqlQuery (ad esempio per riutilizzare una query in modo efficiente) utilizzando il metodo bind().
La clausola facoltativa ORDER BY
indica che i risultati devono essere
ordinati in base alle proprietà specificate, in ordine crescente (ASC
)
o decrescente (DESC
). La clausola ORDER BY
può specificare più ordinamenti come elenco delimitato da virgole, valutato da sinistra a destra. Se la direzione non è specificata, il valore predefinito è ASC
. Se
non viene specificata alcuna clausola ORDER BY
, l'ordine dei risultati non è
definito e potrebbe cambiare nel tempo.
Una clausola LIMIT
facoltativa impedisce alla query di restituire risultati dopo le prime <count>
entità. La clausola LIMIT
può anche includere un <offset>
, per saltare molti risultati e trovare il primo da restituire. Una clausola OFFSET
facoltativa può specificare un valore <offset>
, se non è presente alcuna clausola LIMIT
.
Nota: come il parametro offset
per il metodo fetch(), un OFFSET
in una stringa di query GQL non riduce il numero di entità recuperate dal datastore. Influisce solo sui risultati restituiti
dal metodo fetch(). Una query con un offset ha caratteristiche prestazionali che corrispondono linearmente alla dimensione dell'offset più la dimensione limite.
Per informazioni sull'esecuzione di query GQL, sui parametri di associazione e sull'accesso ai risultati, vedi la classe GqlQuery e il metodo della classe Model.gql().
Esempi
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()
Per trovare tutte le entità del tipo Person
le cui età sono
tra 18 e 35 anni (ovvero sia Charlies che Edna), utilizza questa query:
SELECT * FROM Person WHERE age >= 18 AND age <= 35
Per trovare le tre entità del tipo Person
le cui età sono le
maggiori (ad es. Amy, Betty e Charlie), utilizza questa query:
SELECT * FROM Person ORDER BY age DESC LIMIT 3
Per trovare le entità del tipo Person
i cui nomi sono "Betty" o "Charlie", utilizza questa query:
SELECT * FROM Person WHERE name IN ('Betty', 'Charlie')
Per restituire solo i valori name
per ogni Person
, utilizza
questa query:
SELECT name FROM Person
Per restituire solo i valori name
per ogni Person
,
ordinati per age
, utilizza questa query:
SELECT name FROM Person ORDER BY age
Per trovare le chiavi delle entità del tipo Person
che hanno un'età
di None
(ad es. KEY('Person', 'georgemichael')
), utilizza questa
query:
SELECT __key__ FROM Person WHERE age = NULL
Per trovare tutte le entità, indipendentemente dal tipo, che si trovano nel gruppo di entità di Anna (ad es. Anna e Fred), utilizza questa query:
SELECT * WHERE __key__ HAS ANCESTOR KEY(Person, 'Amy')
Per trovare una corrispondenza in base alla chiave, possiamo utilizzare __key__
sul lato sinistro di una condizione.
Ad esempio, possiamo utilizzarlo per ottenere tutte le entità Person
che hanno un nome utente che inizia con "a".
SELECT * FROM Person WHERE __key__ >= KEY('Person', 'a') AND __key__ < KEY('Person', 'b')
Nota: se crei una query con un'uguaglianza su __key__
, valuta la possibilità di utilizzare get()
invece per recuperare direttamente l'entità.