Nota: gli sviluppatori che creano nuove applicazioni sono vivamente consigliati di utilizzare la libreria client NDB, che presenta numerosi vantaggi rispetto a questa libreria client, come la memorizzazione automatica nella cache delle entità tramite l'API Memcache. Se al momento utilizzi la vecchia libreria client DB, leggi la guida alla migrazione da DB a NDB
Una query di Datastore recupera entità da Cloud Datastore che soddisfano un set di condizioni specificato.
Una query tipica include quanto segue:
- Un tipo di entità a cui si applica la query
- Filtri facoltativi in base alle entità, ai valori delle proprietà, alle chiavi e ai predecessori
- Ordini facoltativi facoltativi per la sequenza dei risultati
Questa pagina descrive la struttura e i tipi di query utilizzati in App Engine per recuperare dati da Cloud Datastore.
Filtri
I filtri di una query impostano i vincoli relativi a proprietà, chiavi e antenati delle entità da recuperare.
Filtri proprietà
Un filtro proprietà specifica
- Il nome di una proprietà
- Un operatore di confronto
- Un valore di proprietà
q = Person.all() q.filter("height <=", max_height)
Il valore della proprietà deve essere fornito dall'applicazione; non può fare riferimento o essere calcolato in altre proprietà. Un'entità soddisfa il filtro se dispone di una proprietà del nome specificato il cui valore è confrontato con il valore specificato nel filtro secondo le modalità descritte dall'operatore di confronto.
L'operatore di confronto può essere uno dei seguenti:
Operatore | Significato |
---|---|
= |
Uguale a |
< |
Minore di |
<= |
Minore o uguale a |
> |
Maggiore di |
>= |
Maggiore o uguale a |
!= |
Diverso da |
IN |
Membro di (uguale a uno dei valori in un elenco specificato) |
L'operatore non uguale (!=
) esegue due query: una in cui tutti gli altri filtri non sono stati modificati e il filtro non uguale è sostituito da un filtro inferiore a (<
) e uno in cui è stato sostituito con un filtro superiore a (>
). I risultati vengono poi uniti, in ordine. Una query non può avere più di un filtro non uguale a una query che non può avere altri filtri di disuguaglianza.
L'operatore IN
inoltre esegue più
query: una per ogni elemento nell'elenco specificato, con tutti gli altri filtri
cambiati e il filtro IN
sostituito con un
filtro di uguaglianza (=
). I risultati vengono uniti nell'ordine degli elementi nell'elenco. Se una query ha più di un filtro IN
, viene eseguita come più query, una per ogni possibile combinazione di valori negli elenchi IN
.
Una singola query contenente
operatori
non-uguale a (!=
)
o IN
è limitata a un massimo di 30 sottoquery.
Filtri principali
Per filtrare in base al valore di una chiave dell'entità, utilizza la proprietà speciale __key__
:
q = Person.all()
q.filter('__key__ >', last_seen_key)
Quando si confronta la disuguaglianza, le chiavi vengono ordinate in base ai seguenti criteri, in ordine:
- Percorso del predecessore
- Tipo di entità
- Identificatore (nome della chiave o ID numerico)
Gli elementi del percorso predecessore vengono confrontati in modo simile: per tipo (stringa), quindi per nome della chiave o ID numerico. I tipi e i nomi delle chiavi sono stringhe e ordinati in base al valore dei byte; gli ID numerici sono numeri interi e sono in ordine numerico. Se le entità con lo stesso tipo padre e tipo utilizzano una combinazione di stringhe di nomi chiave e ID numerici, le entità con ID numerici precedeno quelle con nomi chiave.
Le query sulle chiavi utilizzano indici come le query sulle proprietà e richiedono indici personalizzati negli stessi casi, con un paio di eccezioni: filtri di disuguaglianza o un ordinamento crescente nella chiave non richiedono un indice personalizzato, ma un ordine decrescente della chiave. Come per tutte le query, il server web di sviluppo crea voci appropriate nel file di configurazione degli indici quando viene verificata una query che richiede un indice personalizzato.
Filtri predecessori
Puoi filtrare le query Datastore in base a un predecessore specificato, in modo che i risultati restituiti includano solo le entità discendenti da quel predecessore:
q = Person.all()
q.ancestor(ancestor_key)
Tipi di query speciali
Alcuni tipi specifici di query meritano una menzione speciale:
Query senza tipo
Una query senza tipo e nessun filtro predecessore recupera tutte le entità di un'applicazione da Datastore. Include le entità create e gestite da altre funzionalità di App Engine, come le entità statistiche e le entità di metadati Datastore (se presenti). Tali query senza genere non possono includere filtri o ordinare gli ordini con valori della proprietà. Possono tuttavia filtrare le chiavi delle entità specificando __key__
come nome della proprietà:
q = db.Query()
q.filter('__key__ >', last_seen_key)
In Python, ogni entità restituita dalla query deve avere una classe modello corrispondente definita per il tipo di entità. Per definire le classi di modello per i tipi di entità statistiche, devi importare il pacchetto stats
:
from google.appengine.ext.db import stats
Se l'applicazione ha un valore dell'archivio BLOB, devi aggiungere il seguente codice per ottenere l'API Query per riconoscere il tipo di entità __BlobInfo__
. L'importazione dell'API Blobstore non definisce questa classe.
from google.appengine.ext import db
class BlobInfo(db.Expando):
@classmethod
def kind(cls):
return '__BlobInfo__'
Query dei predecessori
Una query con un filtro predecessore limita i risultati all'entità specificata e ai relativi discendenti:
tom = Person(key_name='Tom')
wedding_photo = Photo(parent=tom)
wedding_photo.image_url='http://domain.com/some/path/to/wedding_photo.jpg'
wedding_photo.put()
baby_photo = Photo(parent=tom)
baby_photo.image_url='http://domain.com/some/path/to/baby_photo.jpg'
baby_photo.put()
dance_photo = Photo(parent=tom)
dance_photo.image_url='http://domain.com/some/path/to/dance_photo.jpg'
dance_photo.put()
camping_photo = Photo()
camping_photo.image_url='http://domain.com/some/path/to/camping_photo.jpg'
camping_photo.put()
photo_query = Photo.all()
photo_query.ancestor(tom)
# This returns wedding_photo, baby_photo, and dance_photo,
# but not camping_photo, because tom is not an ancestor
for photo in photo_query.run(limit=5):
# Do something with photo
Query predecessori senza predecessori
Una query senza tipo che includa un filtro predecessore recupererà il predecessore specificato e tutti i suoi discendenti, indipendentemente dal tipo. Questo tipo di query non richiede indici personalizzati. Come tutte le query senza tipo, non può includere filtri o ordinare gli ordini in base ai valori delle proprietà, ma può filtrare in base alla chiave dell'entità:
q = db.Query()
q.ancestor(ancestor_key)
q.filter('__key__ >', last_seen_key)
Per eseguire una query predecessore mediante GQL (nella console di amministrazione di App Engine o utilizzando la classe GqlQuery
), ometti la clausola FROM
:
q = db.GqlQuery('SELECT * WHERE ANCESTOR IS :1 AND __key__ > :2',
ancestor_key,
last_seen_key)
L'esempio seguente illustra come recuperare tutte le entità discendenti da un dato predecessore:
tom = Person(key_name='Tom')
wedding_photo = Photo(parent=tom)
wedding_photo.image_url='http://domain.com/some/path/to/wedding_photo.jpg'
wedding_photo.put()
wedding_video = Video(parent=tom)
wedding_video.video_url='http://domain.com/some/path/to/wedding_video.avi'
wedding_video.put()
# The following query returns both weddingPhoto and weddingVideo,
# even though they are of different entity kinds
media_query = db.query_descendants(tom)
for media in media_query.run(limit=5):
# Do something with media
Query basate solo su chiavi
Una query basata solo su chiavi restituisce solo le chiavi delle entità dei risultati anziché quelle stesse, con una latenza e un costo inferiori rispetto al recupero di intere entità:
q = Person.all(keys_only=True)
È spesso più economico eseguire prima una query basata solo su chiavi, quindi recuperare un sottoinsieme di entità dai risultati, anziché eseguire una query generale che potrebbe recuperare più entità di quelle effettivamente necessarie.
Query di proiezione
A volte, ciò che ti serve veramente dai risultati di una query sono i valori di alcune proprietà specifiche. In questi casi, puoi utilizzare una query di proiezione per recuperare soltanto le proprietà che ti interessano effettivamente, con una latenza e un costo inferiori rispetto al recupero dell'intera entità. Per informazioni dettagliate, visita la pagina Query di proiezione.
Ordinamenti
Un ordine di query della query specifica
- Il nome di una proprietà
- Ordine (ordine crescente o decrescente)
In Python, l'ordinamento decrescente è indicato da un trattino (-
) prima del nome della proprietà; l'omissione del trattino specifica per impostazione predefinita l'ordine crescente. Ad esempio:
# Order alphabetically by last name: q = Person.all() q.order('last_name') # Order by height, tallest to shortest: q = Person.all() q.order('-height')
Se una query include più ordinamenti, questi vengono applicati nella sequenza specificata. L'esempio seguente ordina prima il cognome e poi l'altezza decrescente:
q = Person.all() q.order('lastName') q.order('-height')
Se non vengono specificati ordini di ordinamento, i risultati vengono restituiti nell'ordine in cui vengono recuperati da Datastore.
Nota: a causa del modo in cui Datastore esegue le query, se una query specifica filtri di disuguaglianza su una proprietà e ordini su altre proprietà, la proprietà utilizzata nei filtri di uguaglianza deve essere ordinata prima delle altre proprietà.
Indici
Ogni query di Datastore calcola i risultati utilizzando uno o più indici, che contengono chiavi di entità in una sequenza specificata dalle proprietà dell'indice e, facoltativamente, dei predecessori dell'entità. Gli indici vengono aggiornati in modo incrementale per riflettere le modifiche che l'applicazione apporta alle sue entità, in modo che i risultati corretti di tutte le query siano disponibili senza bisogno di ulteriori computing.
App Engine predefinisce un semplice indice su ogni proprietà di un'entità.
Un'applicazione App Engine può definire ulteriori indici personalizzati in un
file di configurazione
degli indici denominato
index.yaml
. Il server di sviluppo aggiunge automaticamente suggerimenti a questo file quando rileva query che non possono essere eseguite con gli indici esistenti.
Puoi regolare manualmente gli indici modificando il file prima di caricare l'applicazione.
Esempio di interfaccia delle query
L'API Python Datastore fornisce due classi per la preparazione e l'esecuzione delle query:
Query
utilizza le chiamate dei metodi per preparare la query.GqlQuery
utilizza un linguaggio di query di tipo SQL chiamato GQL per preparare la query da una stringa di query.
class Person(db.Model):
first_name = db.StringProperty()
last_name = db.StringProperty()
city = db.StringProperty()
birth_year = db.IntegerProperty()
height = db.IntegerProperty()
# Query interface constructs a query using instance methods
q = Person.all()
q.filter("last_name =", "Smith")
q.filter("height <=", max_height)
q.order("-height")
# GqlQuery interface constructs a query using a GQL query string
q = db.GqlQuery("SELECT * FROM Person " +
"WHERE last_name = :1 AND height <= :2 " +
"ORDER BY height DESC",
"Smith", max_height)
# Query is not executed until results are accessed
for p in q.run(limit=5):
print "%s %s, %d inches tall" % (p.first_name, p.last_name, p.height)
Passaggi successivi
- Scopri come specificare cosa restituisce una query e controlla ulteriormente i risultati della query.
- Scopri le limitazioni comuni per le query su Cloud Datastore.
- Scopri di più sui cursori di query, che consentono a un'applicazione di recuperare le query in pratiche batch.
- Scopri la coerenza dei dati e come funziona la coerenza dei dati con i diversi tipi di query su Cloud Datastore.