Riferimento GQL per Python NDB/DB

GQL è un linguaggio simile a SQL per il recupero di entità e chiavi. La sintassi delle query GQL è simile a quella di SQL. Questa pagina è un riferimento per l'utilizzo di GQL con le librerie client NDB e DB Python.

GQL corrisponde approssimativamente a SQL: puoi considerare un kind GQL come una tabella SQL, un entity GQL come una riga SQL e un property GQL come una colonna SQL. Tuttavia, una ricerca SQL di riga-colonna è 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:

Sintassi

La sintassi 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 con 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 le istruzioni SELECT.

Una query GQL restituisce zero o più entità, entità previste 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à dell'entità che devono essere restituite dalla query. Una query GQL non può eseguire una query "join" di tipo SQL.

Suggerimento: le query SELECT __key__ or SELECT <property list> sono più veloci e utilizzano meno tempo di CPU rispetto a SELECT * query.

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à previste.

La clausola facoltativa FROM limita l'insieme di risultati alle entità del tipo specificato. Una query senza una clausola FROM viene chiamata query senza genere e può avere solo un elemento 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 assegnate 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 un formato limitato di OR.

L'operatore IN confronta il valore di una proprietà con ogni elemento in un elenco. L'operatore IN equivale a molte query =, una per ogni valore, collegate tramite OR. Per la query è possibile restituire 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 sul datastore sottostante distinta per ogni elemento nell'elenco. Le entità restituite sono il risultato dell'analisi incrociata di tutte le query sottostanti sul datastore e vengono 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à. Un tipico nome di proprietà è composto da caratteri alfanumerici facoltativamente 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 (in base al tipo di dati della proprietà):

  • un valore letterale str, come stringa tra virgolette singole. Le virgolette singole nella stringa devono essere convertite in caratteri di escape come ''. Ad esempio: 'Joe''s Diner'
  • un valore letterale di numero intero o in virgola mobile. Ad esempio: 42.7
  • un valore letterale booleano, ad esempio TRUE o FALSE.
  • il valore letterale NULL, che rappresenta il valore null (None in Python).
  • un valore letterale data/ora, data/ora, con valori numerici o una rappresentazione 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 di entità, con una chiave con codifica stringa o un percorso completo dei tipi e dei nomi/ID delle chiavi:

    • KEY('encoded key')
    • KEY('kind', 'name'/ID [, 'kind', 'name'/ID...])
  • Un valore letterale dell'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, i parametri di posizione sono indicati in base a un numero: title = :1. Ai parametri parola chiave viene fatto riferimento in base al nome: title = :mytitle

Nota: le condizioni del modulo property = NULL verificano se un valore null è archiviato esplicitamente nel datastore per quella proprietà. Non è la stessa cosa che verificare se l'entità è priva di qualsiasi 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 di parole chiave passati al costruttore GqlQuery o al metodo gql() di una classe di modello. I tipi di dati della proprietà che non hanno la sintassi del valore letterale corrispondente devono essere specificati utilizzando l'associazione di parametri, incluso il tipo di dati dell'elenco. Le associazioni di parametri possono essere restituite con nuovi valori durante il ciclo di vita dell'istanza GqlQuery (ad esempio per riutilizzare una query in modo efficiente) usando il metodo bind().

La clausola facoltativa ORDER BY indica che i risultati devono essere restituiti 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 fa sì che la query interrompa la restituzione dei risultati dopo le prime <count> entità. La clausola LIMIT può anche includere un <offset>, per saltare così tanti risultati e trovare il primo risultato da restituire. Una clausola OFFSET facoltativa può specificare una clausola <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. ma solo quali risultati vengono restituiti dal metodo fetch(). Una query con un offset ha caratteristiche di prestazioni che corrispondono linearmente alla dimensione dell'offset più la dimensione limite.

Per informazioni sull'esecuzione di query GQL, sull'associazione dei parametri e sull'accesso ai risultati, consulta 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 la cui età è compresa tra 18 e 35 anni (ad es. sia Carlo che Gianni), 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 più grandi (ad esempio Anna, Betty e Carlo), 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, ordinato 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à pari a None (ossia 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 Amy (ad es. Anna e Federico), utilizza questa query:

SELECT * WHERE __key__ HAS ANCESTOR KEY(Person, 'Amy')

Per creare una corrispondenza per 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() per recuperare direttamente l'entità.