Query di proiezione

Nota:gli sviluppatori che creano nuove applicazioni sono fortemente incoraggiati a utilizzare la libreria client NDB, che offre diversi vantaggi rispetto a questa libreria client, ad esempio la memorizzazione automatica nella cache delle entità tramite l'API Memcache. Se al momento utilizzi la libreria client DB precedente, leggi la guida alla migrazione da DB a NDB.

La maggior parte delle query Datastore restituisce entità intere come risultati, ma spesso un'applicazione è interessata solo ad alcune delle proprietà dell'entità. Le query di proiezione ti consentono di eseguire query su Datastore solo per le proprietà specifiche di un'entità di cui hai effettivamente bisogno, con latenza e costi inferiori rispetto al recupero dell'intera entità.

Le query di proiezione sono simili alle query SQL del modulo:

SELECT name, email, phone FROM CUSTOMER

Puoi utilizzare tutte le funzionalità di filtro e ordinamento disponibili per le query standard sulle entità, nel rispetto delle limitazioni descritte di seguito. La query restituisce risultati abbreviati con solo le proprietà specificate (name, email e phone nell'esempio) compilate con i valori; tutte le altre proprietà non contengono dati.

Utilizzo delle query di proiezione in Python 2

Specifichi una proiezione in questo modo: Le query di proiezione sono supportate dagli oggetti Query e GqlQuery. Entrambi i corsi richiedono questa importazione:

from google.appengine.ext import db

Specifica una proiezione in questo modo:

proj = db.Query(entity_name, projection=('property_1', 'property_2','property_n'))

proj = db.GqlQuery("SELECT property_1, property_2, property_n FROM entity_name")

Gestisci i risultati di queste query proprio come faresti per una query di entità standard, ad esempio scorrendo i risultati.

Le seguenti query di esempio cercano le proprietà title, read_path e date_written di tutte le voci EventLog, ordinate in ordine crescente in base a date_written, e scrivono il valore di ogni proprietà nel log dell'applicazione:

for proj in db.GqlQuery("SELECT title, read_path, date_written" +
                        "FROM EventLog" +
                        "ORDER BY date_written ASC"):
  logging.info(proj.title)
  logging.info(proj.read_path)
  logging.info(proj.date_written)

Raggruppamento(sperimentale)

Le query di proiezione possono utilizzare la parola chiave distinct per garantire che in un set di risultati vengano restituiti solo risultati completamente unici. Verrà restituito solo il primo risultato per le entità che hanno gli stessi valori per le proprietà proiettate.

query = db.Query(projection=['A', 'B'], distinct=True).filter('B >', 1).order('-B, A')

Limitazioni delle proiezioni

Le query di proiezione sono soggette alle seguenti limitazioni:

  • È possibile proiettare solo le proprietà indicizzate.

    La proiezione non è supportata per le proprietà non indicizzate, né in modo esplicito né implicito. Le stringhe di testo lunghe (Text) e le stringhe di byte lunghe (Blob) non vengono indicizzate.

  • La stessa proprietà non può essere proiettata più di una volta.

  • Le proprietà a cui viene fatto riferimento in un filtro di uguaglianza (=) o appartenenza (IN) non possono essere proiettate.

    Ad esempio,

    SELECT A FROM kind WHERE B = 1
    

    è valido (la proprietà proiettata non viene utilizzata nel filtro di uguaglianza), così come

    SELECT A FROM kind WHERE A > 1
    

    (non è un filtro di uguaglianza), ma

    SELECT A FROM kind WHERE A = 1
    

    (projected property used in equality filter) non lo è.

  • I risultati restituiti da una query di proiezione non possono essere salvati nuovamente in Datastore.

    Poiché la query restituisce risultati compilati solo parzialmente, non puoi scriverli di nuovo in Datastore.

Proiezioni e proprietà con più valori

La proiezione di una proprietà con più valori non comporterà il popolamento di tutti i valori per quella proprietà. Viene restituita un'entità separata per ogni combinazione univoca di valori proiettati corrispondente alla query. Ad esempio, supponiamo di avere un'entità di tipo Foo con due proprietà multivalore, A e B:

entity = Foo(A=[1, 1, 2, 3], B=['x', 'y', 'x'])

Quindi la query di proiezione

SELECT A, B FROM Foo WHERE A < 3

restituirà quattro entità con le seguenti combinazioni di valori:

A = 1, B = 'x'
A = 1, B = 'y'
A = 2, B = 'x'
A = 2, B = 'y'

Tieni presente che se un'entità ha una proprietà con più valori senza valori, non verranno incluse voci nell'indice e non verranno restituiti risultati per l'entità da una query di proiezione che include la proprietà.

Indici per le proiezioni

Le query di proiezione richiedono che tutte le proprietà specificate nella proiezione siano incluse in un indice Datastore. Il server di sviluppo di App Engine genera automaticamente gli indici necessari nel file di configurazione dell'indice, index.yaml, che viene caricato con l'applicazione.

Un modo per ridurre al minimo il numero di indici richiesti è proiettare le stesse proprietà in modo coerente, anche quando non sono sempre necessarie. Ad esempio, queste query richiedono due indici separati:

SELECT A, B FROM Kind
SELECT A, B, C FROM Kind

Tuttavia, se proietti sempre le proprietà A, B e C, anche quando C non è obbligatorio, sarà necessario un solo indice.

La conversione di una query esistente in una query di proiezione potrebbe richiedere la creazione di un nuovo indice se le proprietà nella proiezione non sono già incluse in un'altra parte della query. Ad esempio, supponiamo di avere una query esistente come

SELECT * FROM Kind WHERE A > 1 ORDER BY A, B

che richiede l'indice

Index(Kind, A, B)

Conversione in una delle query di proiezione

SELECT C FROM Kind WHERE A > 1 ORDER BY A, B
SELECT A, B, C FROM Kind WHERE A > 1 ORDER BY A, B

introduce una nuova proprietà (C) e pertanto richiederà la creazione di un nuovo indice Index(Kind, A, B, C). Tieni presente che la query di proiezione

SELECT A, B FROM Kind WHERE A > 1 ORDER BY A, B

non modificherebbe l'indice richiesto, poiché le proprietà proiettate A e B erano già incluse nella query esistente.