La libreria client NDB di Google Datastore consente alle app Python di App Engine di connettersi a Datastore. La libreria client NDB si basa sulla libreria DB Datastore precedente aggiungendo le seguenti funzionalità di datastore:
- La classe
StructuredProperty
, che consente alle entità di avere una struttura nidificata. - Memorizzazione nella cache automatica integrata, che in genere fornisce letture rapide ed economiche tramite una cache contestuale e Memcache.
- Supporta entrambe le API asincrone per azioni simultanee, oltre alle API sincrone.
Questa pagina fornisce un'introduzione e una panoramica della libreria client NDB di App Engine. Per informazioni su come eseguire la migrazione a Cloud NDB, che supporta Python 3, consulta Migrazione a Cloud NDB.
Definizione di entità, chiavi e proprietà
Datastore archivia gli oggetti di dati, chiamati entità. Un'entità ha una o più proprietà, con valori denominati di uno dei diversi tipi di dati supportati. Ad esempio, una proprietà può essere una stringa, un numero intero o un riferimento a un'altra entità.
Ogni entità è identificata da una chiave, ovvero un identificatore univoco all'interno del datastore dell'applicazione. La chiave può avere un elemento parent e un'altra chiave. Questo padre può avere a sua volta un elemento padre e così via; nella parte superiore di questa "catena" di elementi padre c'è una chiave senza padre, denominata root.
Le entità le cui chiavi hanno la stessa radice formano un gruppo di entità o un gruppo. Se le entità si trovano in gruppi diversi, a volte le modifiche a queste entità potrebbero sembrare "non nell'ordine corretto". Se le entità non sono correlate nella semantica dell'applicazione, non è un problema. Tuttavia, se le modifiche di alcune entità devono essere coerenti, l'applicazione dovrebbe renderle parte dello stesso gruppo durante la creazione.
Il seguente diagramma del rapporto tra entità ed esempio di codice mostrano come Guestbook
può avere più Greetings
, ciascuno con proprietà content
e date
.
Questa relazione è implementata nell'esempio di codice riportato di seguito.
Utilizzo dei modelli per l'archiviazione dei dati
Un modello è una classe che descrive un tipo di entità, inclusi i tipi e la configurazione delle sue proprietà. È più o meno simile a una tabella in SQL. Un'entità può essere creata chiamando il costruttore della classe del modello e quindi archiviata chiamando il metodo put()
.
Questo codice campione definisce la classe del modello Greeting
. Ogni entità Greeting
ha due proprietà: il contenuto testuale del saluto e la data di creazione,
Per creare e archiviare un nuovo saluto, l'applicazione crea un nuovo oggetto Greeting
e chiama il relativo metodo put()
.
Per assicurarti che i saluti in un guestbook non appaiano "non disponibili ", l'applicazione imposta una chiave padre durante la creazione di un nuovo Greeting
.
Pertanto, il nuovo saluto si troverà nello stesso gruppo di entità degli altri saluti nello stesso guestbook. L'applicazione usa questo fatto durante l'esecuzione di query: usa una query da predecessore.
Query e indici
Un'applicazione può eseguire query per trovare le entità che corrispondono ad alcuni filtri.
Una tipica query NDB filtra le entità per tipo. In questo esempio, query_book
genera una query che restituisce Greeting
entità. Una query può anche specificare filtri su chiavi e valori della proprietà dell'entità.
Come in questo esempio, una query può specificare un predecessore, trovando solo le entità "appartenenti a" un predecessore. Una query può specificare l'ordinamento. Se una determinata entità ha almeno un valore (possibilmente nullo) per ogni proprietà nei filtri e negli ordini e tutti i criteri del filtro sono soddisfatti dai valori della proprietà, l'entità viene restituita di conseguenza.
Ogni query utilizza un indice, ovvero una tabella che contiene i risultati della query nell'ordine desiderato. Il datastore sottostante gestisce automaticamente indici semplici (indici che utilizzano una sola proprietà).
Definisce i suoi indici complessi in un file di configurazione index.yaml
. Il server web di sviluppo aggiunge automaticamente suggerimenti a questo file quando rileva query per cui non sono ancora stati configurati indici.
Puoi ottimizzare gli indici manualmente modificando il file prima di caricare
l'applicazione. Puoi aggiornare gli indici separatamente dal caricamento dell'applicazione eseguendo gcloud app deploy index.yaml
.
Se il tuo datastore ha molte entità, la creazione di un nuovo indice richiede molto tempo; in questo caso, conviene aggiornare le definizioni dell'indice prima di caricare il codice che utilizza il nuovo indice. Puoi usare la console di amministrazione
per sapere quando termina la creazione degli indici.
Questo meccanismo di indice supporta un'ampia gamma di query ed è adatto alla maggior parte delle applicazioni. Tuttavia, non supporta alcuni tipi di query comuni in altre tecnologie di database. In particolare, le unioni non sono supportate.
Informazioni sulle scritture NDB: commit, invalida cache e applica
NDB scrive i dati nei passaggi:
- Nella fase di commit, il servizio Datastore sottostante registra le modifiche.
- NDB rende non valide le proprie cache delle entità/entità interessate. Di conseguenza, le letture future leggeranno (e memorizzeranno nella cache) il Datastore sottostante invece di leggere i valori inattivi dalla cache.
- Infine, forse alcuni secondi dopo, il datastore sottostante applica la modifica. Rende la modifica visibile alle query globali e, alla fine, genera letture coerenti.
La funzione NDB che scrive i dati (ad esempio put()
) restituisce dopo l'annullamento della convalida della cache; la fase Applica avviene in modo asincrono.
Se si verifica un errore durante la fase di commit, vengono eseguiti nuovi tentativi automatici, ma se gli errori continuano, l'applicazione riceve un'eccezione. Se la fase di commit ha esito positivo, ma l'applicazione non va a buon fine, il comando Applica viene riportato fino al completamento quando si verifica una delle seguenti condizioni:
- Lo "sweep" di Datastore periodico verifica la presenza di job di commit non completati e li applica.
- La successiva scrittura, transazione o lettura molto coerente nel gruppo di entità interessato causa l'applicazione delle modifiche non ancora applicate prima della lettura, della scrittura o della transazione.
Questo comportamento influisce su come e quando i dati sono visibili alla tua applicazione. La modifica potrebbe non essere applicata completamente al datastore sottostante qualche centinaio di millisecondi dopo il ritorno della funzione NDB. Una query non predecessore eseguita durante l'applicazione di una modifica potrebbe notare uno stato incoerente, ovvero una parte della modifica, ma non l'intera.
Transazioni e dati di memorizzazione nella cache
La libreria client NDB può raggruppare più operazioni in una singola transazione. La transazione non può avere esito positivo se non vengono eseguite tutte le operazioni nella transazione. Se una delle operazioni non va a buon fine, viene eseguito automaticamente il rollback della transazione. Ciò è particolarmente utile per le applicazioni web distribuite, in cui più utenti potrebbero accedere o manipolare gli stessi dati contemporaneamente.
NDB utilizza Memcache come servizio di cache per gli "hot spot" dei dati. Se l'applicazione legge spesso alcune entità, NDB è in grado di leggerle rapidamente dalla cache.
Utilizzo di Django con NDB
Per utilizzare NDB con il framework web di Django, aggiungi google.appengine.ext.ndb.django_middleware.NdbDjangoMiddleware
alla voce MIDDLEWARE_CLASSES
nel file settings.py
di Django. È meglio inserirlo prima di qualsiasi altra classe middleware, poiché alcuni altri middleware potrebbero effettuare chiamate al datastore e queste non verranno gestite correttamente se il middleware viene richiamato prima di questo middleware. Puoi scoprire di più sul middleware Django.
Passaggi successivi
Scopri di più su:
- Creazione di entità in NDB.
- Modalità di elaborazione delle transazioni in Datastore.
- Come creare e formattare una query con la libreria client NDB.
- Memorizzazione nella cache dei dati mediante NDB e l'infrastruttura memcache sottostante.
- Amministrazione e gestione dei dati archiviati in Datastore.