Firestore in modalità Datastore (Datastore) supporta diversi tipi di dati per i valori delle proprietà. Sono inclusi, tra gli altri:
- Numeri interi
- Numeri in virgola mobile
- Stringa
- Date
- Dati binari
Per un elenco completo dei tipi, consulta proprietà e tipi di valori.
Proprietà e tipi di valori
I valori dei dati associati a un'entità sono costituiti da una o più proprietà. Ogni proprietà ha un nome e uno o più valori. Una proprietà può avere valori di più di un tipo e due entità possono avere valori di tipi diversi per la stessa proprietà. Le proprietà possono essere indicizzate o non indicizzate (le query che ordinano o filtrano una proprietà P ignorano le entità in cui P non è indicizzata). Un'entità può avere al massimo 20.000 proprietà indicizzate.
Sono supportati i seguenti tipi di valori:
Quando una query coinvolge una proprietà con valori di tipi misti, Datastore utilizza un ordinamento deterministico basato sulle rappresentazioni interne:
- Valori null
- Numeri in virgola fissa
- Numeri interi
- Date e ore
- Valori booleani
- Sequenze di byte
- Stringa Unicode
- Chiavi Blobstore
- Chiavi Datastore
Poiché le stringhe di testo lunghe e le stringhe di byte lunghe non sono indicizzate, non hanno un ordinamento definito.
Tipi di proprietà
NDB supporta i seguenti tipi di proprietà:
| Property type | Descrizione |
|---|---|
IntegerProperty |
Numero intero con segno a 64 bit |
FloatProperty |
Numero in virgola mobile a precisione doppia |
BooleanProperty |
Booleano |
StringProperty |
Stringa Unicode; fino a 1500 byte, indicizzata |
TextProperty |
Stringa Unicode; lunghezza illimitata, non indicizzata |
BlobProperty |
Stringa di byte non interpretata: se imposti indexed=True, fino a 1500 byte, indicizzata;se indexed è False (il valore predefinito), lunghezza illimitata, non indicizzata.Argomento della parola chiave facoltativo: compressed. |
DateTimeProperty |
Data e ora (vedi Proprietà data e ora) |
DateProperty |
Data (vedi Proprietà di data e ora) |
TimeProperty |
Ora (vedi Proprietà di data e ora) |
GeoPtProperty |
Località geografica. Questo è un oggetto ndb.GeoPt. L'oggetto ha gli attributi lat e lon, entrambi float. Puoi crearne uno con due numeri in virgola mobile, ad esempio ndb.GeoPt(52.37, 4.88), o con una stringa, ad esempio ndb.GeoPt("52.37, 4.88"). (Questo è lo stesso corso di db.GeoPt) |
KeyProperty |
Chiave Datastore Argomento parola chiave facoltativo: kind=kind, per richiedere che le chiavi assegnate a questa proprietà abbiano sempre il tipo indicato. Può essere una stringa o una sottoclasse di Model. |
BlobKeyProperty |
Chiave Blobstore Corrisponde a BlobReferenceProperty nella vecchia API db, ma il valore della proprietà è un BlobKey anziché un BlobInfo; puoi creare un BlobInfo da questo valore utilizzando BlobInfo(blobkey) |
UserProperty |
Oggetto utente. |
StructuredProperty |
Include un tipo di modello all'interno di un altro, per valore (vedi Proprietà strutturate) |
LocalStructuredProperty |
Come StructuredProperty, ma la rappresentazione su disco è un blob opaco e non viene indicizzata (vedi Proprietà strutturate).Argomento facoltativo della parola chiave: compressed. |
JsonProperty |
Il valore è un oggetto Python (ad esempio un elenco, un dizionario o una stringa) serializzabile utilizzando il modulo json di Python. Datastore memorizza la serializzazione JSON come blob. Non indicizzato per impostazione predefinita.Argomento della parola chiave facoltativo: compressed. |
PickleProperty |
Value è un oggetto Python (ad esempio un elenco, un dizionario o una stringa) serializzabile utilizzando il protocollo pickle di Python. Datastore memorizza la serializzazione pickle come blob. Non indicizzato per impostazione predefinita. Argomento della parola chiave facoltativo: compressed. |
GenericProperty |
Valore generico Utilizzato principalmente dalla classe Expando, ma utilizzabile anche in modo esplicito. Il tipo può essere uno qualsiasi tra int, long, float, bool, str, unicode, datetime, Key, BlobKey, GeoPt, User e None. |
ComputedProperty |
Valore calcolato da altre proprietà mediante una funzione definita dall'utente;utente. (vedi Proprietà calcolate). |
Alcune di queste proprietà hanno un argomento parola chiave facoltativo,
compressed. Se la proprietà ha compressed=True, i relativi dati vengono compressi
con gzip sul disco. Occupa meno spazio, ma richiede la CPU per la codifica/decodifica nelle operazioni di scrittura e lettura.
Sia la compressione che la decompressione sono "pigre"; un valore della proprietà compresso verrà decompresso solo la prima volta che vi accedi. Se leggi un'entità contenente un valore della proprietà compresso e lo riscrivi senza accedere alla proprietà compressa, non verrà decompresso e compresso. Anche la cache in contesto partecipa a questo schema lazy, ma memcache memorizza sempre il valore compresso per le proprietà compresse.
A causa del tempo di CPU aggiuntivo necessario per la compressione, in genere è meglio utilizzare le proprietà compresse solo se i dati sarebbero troppo grandi per essere contenuti senza. Ricorda che la compressione basata su gzip in genere non è efficace per le immagini e altri dati multimediali, poiché questi formati sono già compressi utilizzando un algoritmo di compressione specifico per i contenuti multimediali (ad es. JPEG per le immagini).
Opzioni proprietà
La maggior parte dei tipi di proprietà supporta alcuni argomenti standard. Il primo è un argomento posizionale facoltativo che specifica il nome Datastore della proprietà. Puoi utilizzarlo per assegnare alla proprietà un nome diverso in Datastore rispetto al punto di vista dell'applicazione. Un utilizzo comune è ridurre lo spazio in Datastore, consentendo a Datastore di utilizzare nomi di proprietà abbreviati mentre il tuo codice utilizza nomi più lunghi e significativi. Ad esempio,
Ciò è particolarmente utile per le proprietà ripetute per le quali prevedi molti valori per entità.
Inoltre, la maggior parte dei tipi di proprietà supporta i seguenti argomenti delle parole chiave:
| Argomento | Tipo | Predefinito | Descrizione |
|---|---|---|---|
indexed |
bool |
Di solito True |
Includi la proprietà negli indici di Datastore. Se False, non è possibile eseguire query sui valori, ma le scritture sono più veloci. Non tutti i tipi di proprietà supportano l'indicizzazione; l'impostazione di indexed su True non va a buon fine per questi tipi.Le proprietà non indicizzate costano meno operazioni di scrittura rispetto a quelle indicizzate. |
repeated |
bool |
False |
Il valore della proprietà è un elenco Python contenente i valori del tipo sottostante (vedi Proprietà ripetute). Non può essere combinato con required=True o default=True. |
required |
bool |
False |
La proprietà deve avere un valore specificato. |
default |
Tipo sottostante della proprietà | Nessuno | Valore predefinito della proprietà se non ne è specificato esplicitamente nessuno. |
choices |
Elenco dei valori del tipo sottostante | None |
Elenco facoltativo di valori consentiti. |
validator |
Funzione | None |
Funzione facoltativa per convalidare ed eventualmente forzare il valore. Verrà chiamato con gli argomenti (prop, value) e deve restituire il valore (eventualmente forzato) o generare un'eccezione. Se si chiama di nuovo la funzione su un valore forzato, il valore non deve essere modificato ulteriormente. Ad esempio, restituire value.strip() o value.lower() è consentito, ma non value + '$'. Può anche restituire None, che significa "nessuna modifica". Vedi anche Scrittura nelle sottoclassi di proprietà. |
verbose_name |
stringa | None |
Etichetta HTML facoltativa da utilizzare in framework di moduli web come jinja2. |
Proprietà ripetute
Qualsiasi proprietà con repeated=True diventa una proprietà ripetuta. La proprietà
accetta un elenco di valori del tipo sottostante, anziché un singolo valore. Ad esempio, il valore di una proprietà definita con IntegerProperty(repeated=True) è un elenco di numeri interi.
Datastore potrebbe visualizzare più valori per una proprietà di questo tipo. Viene creato un record di indice separato per ogni valore. Ciò influisce sulla semantica delle query; per un esempio, vedi Esecuzione di query per proprietà ripetute.
Questo esempio utilizza una proprietà ripetuta:
...
Viene creata un'entità Datastore con il seguente contenuto:
Quando esegui una query per la proprietà tags, questa entità soddisferà una query per 'python' o 'ruby'.
Quando aggiorni una proprietà ripetuta, puoi assegnarle un nuovo elenco o modificare
l'elenco esistente sul posto. Quando assegni un nuovo elenco, i tipi degli elementi
dell'elenco vengono convalidati immediatamente. I tipi di elementi non validi (ad esempio, l'assegnazione di
[1, 2] a art.tags sopra) generano un'eccezione. Quando modifichi l'elenco,
la modifica non viene convalidata immediatamente. Il valore verrà invece convalidato
quando scrivi l'entità in Datastore.
Datastore conserva l'ordine degli elementi dell'elenco in una proprietà ripetuta, in modo da poter assegnare un significato al loro ordine.
Proprietà di data e ora
Sono disponibili tre tipi di proprietà per memorizzare i valori relativi a date e ore:
DatePropertyTimePropertyDateTimeProperty
Questi accettano valori appartenenti alle classi corrispondenti (date, time,
datetime) del modulo datetime standard di Python. Il più generale dei tre è DateTimeProperty, che indica sia una data del calendario sia un'ora del giorno; gli altri sono occasionalmente utili per scopi speciali che richiedono solo una data (ad esempio una data di nascita) o solo un'ora (ad esempio l'ora di una riunione). Per
motivi tecnici, DateProperty e TimeProperty sono sottoclassi di
DateTimeProperty, ma non devi fare affidamento su questa relazione di ereditarietà
(e tieni presente che è diversa dalle relazioni di ereditarietà tra le
classi sottostanti definite dal modulo datetime stesso).
Ognuna di queste proprietà ha due opzioni di parole chiave booleane aggiuntive:
| Opzione | Descrizione |
|---|---|
auto_now_add |
Imposta la proprietà sulla data/ora corrente quando viene creata l'entità. Puoi eseguire l'override manuale di questa proprietà. Quando l'entità viene aggiornata, la proprietà non cambia. Per questo comportamento, utilizza auto_now. |
auto_now |
Imposta la proprietà sulla data/ora corrente quando viene creata l'entità e ogni volta che viene aggiornata. |
Queste opzioni non possono essere combinate con repeated=True. Entrambi i valori predefiniti sono
False; se entrambi sono impostati su True, auto_now ha la precedenza. È possibile
ignorare il valore di una proprietà con auto_now_add=True, ma non con
auto_now=True. Il valore automatico non viene generato finché l'entità non viene
scritta, ovvero queste opzioni non forniscono valori predefiniti dinamici. (Questi dettagli
sono diversi dalla vecchia API db.)
Proprietà strutturate
Puoi strutturare le proprietà di un modello. Ad esempio, puoi definire una classe di modello Contact contenente un elenco di indirizzi, ognuno con una struttura interna.
Le proprietà strutturate (tipo StructuredProperty``) ti consentono di farlo; ad esempio:
...
...
In questo modo viene creata una singola entità Datastore con le seguenti proprietà:
La lettura di un'entità di questo tipo ricostruisce esattamente l'entità Contact originale.
Sebbene le istanze Address siano definite utilizzando la stessa sintassi delle classi di modelli, non sono entità complete. Non hanno chiavi proprie in
Datastore. Non possono essere recuperati indipendentemente dall'entità
Contact a cui appartengono. Un'applicazione può, tuttavia, eseguire query per i valori dei singoli campi. Vedi Filtro per valori di proprietà strutturati.
Tieni presente che address.type, address.street e address.city sono considerati
array paralleli dal punto di vista di Datastore, ma la libreria NDB
nasconde questo aspetto e crea l'elenco corrispondente di istanze Address.
Puoi specificare le opzioni delle proprietà abituali per le proprietà strutturate
(tranne indexed). Il nome Datastore è il secondo
argomento posizionale in questo caso (il primo è la classe del modello utilizzata per definire
la sottostruttura).
Quando non è necessario eseguire query per le proprietà interne di una sottostruttura, puoi
utilizzare una proprietà strutturata locale (LocalStructuredProperty). Se
sostituisci StructuredProperty con LocalStructuredProperty nell'esempio
precedente, il comportamento del codice Python è lo stesso, ma Datastore vede solo un blob opaco per ogni indirizzo. L'entità guido creata nell'esempio
verrebbe archiviata nel seguente modo:
name = 'Guido'
address = <opaque blob for {'type': 'home', 'city': 'Amsterdam'}>
address = <opaque blob for {'type': 'work', 'city': 'SF',
'street': 'Spear St'}>
L'entità verrà letta correttamente. Poiché le proprietà di questo tipo non sono mai indicizzate, non puoi eseguire query per i valori degli indirizzi.
Proprietà calcolate
Le proprietà calcolate (ComputedProperty) sono proprietà di sola lettura il cui valore
viene calcolato a partire da altri valori di proprietà da una funzione fornita dall'applicazione. Tieni presente
che una proprietà calcolata supporta solo i tipi supportati dalle proprietà
generiche. Il valore calcolato viene scritto in Datastore in modo che
possa essere interrogato e visualizzato nel visualizzatore Datastore, ma
il valore memorizzato viene ignorato quando l'entità viene letta da Datastore; al contrario, il valore viene ricalcolato chiamando la funzione
ogni volta che viene richiesto. Ad esempio:
...
Questo archivia un'entità con i seguenti valori delle proprietà:
Se cambiamo il nome in "Nickie" e chiediamo il valore di name_lower, viene restituito
"nickie":
Proprietà dei messaggi RPC di Google Protocol
La libreria Google Protocol RPC utilizza oggetti Message per i dati strutturati, che possono rappresentare richieste RPC, risposte o altro. NDB fornisce un'API per l'archiviazione di oggetti Message
Google Protocol RPC come proprietà di entità. Supponiamo di definire una sottoclasse Message:
...
Puoi archiviare gli oggetti Note in Datastore come valori delle proprietà delle entità
utilizzando l'API msgprop di NDB.
...
...
Se vuoi eseguire query per i nomi dei campi, questi devono essere indicizzati. Puoi specificare un elenco di nomi di campi che verranno indicizzati con il parametro indexed_fields per MessageProperty.
MessageProperty supporta molte, ma non tutte, le opzioni della proprietà. Supporta:
namerepeatedrequireddefaultchoicesvalidatorverbose_name
Le proprietà dei messaggi non supportano l'opzione di proprietà indexed; non puoi indicizzare
i valori Message. Puoi indicizzare i campi di un messaggio come descritto sopra.
Funzionano anche i messaggi nidificati (utilizzando MessageField):
...
MessageProperty ha un'opzione di proprietà speciale, protocol, che specifica in che modo
l'oggetto messaggio viene serializzato in Datastore. I valori sono
nomi di protocolli utilizzati dalla classe protorpc.remote.Protocols. I nomi dei protocolli supportati sono protobuf e protojson; il valore predefinito è protobuf.
msgprop definisce anche EnumProperty, un tipo di proprietà che può essere utilizzato per
memorizzare un valore protorpc.messages.Enum in un'entità. Esempio:
...
...
EnumProperty memorizza il valore come numero intero; infatti, EnumProperty è una
sottoclasse di IntegerProperty. Ciò implica che puoi rinominare i valori enum
senza dover modificare le entità già archiviate, ma non puoi rinumerarli.
EnumProperty supporta le seguenti opzioni di proprietà:
nameindexedrepeatedrequireddefaultchoicesvalidatorverbose_name
Informazioni sui modelli di entità NDB
Un modello di entità NDB può definire proprietà. Le proprietà delle entità sono un po' come i membri di dati delle classi Python, un modo strutturato per contenere i dati; sono anche un po' come i campi di uno schema di database.
Un'applicazione tipica definisce un modello dei dati definendo una classe che eredita
da Model con alcuni attributi della classe di proprietà. Ad esempio:
...
In questo caso, username, userid e email sono proprietà di Account.
Esistono diversi altri tipi di proprietà. Alcuni sono utili per rappresentare date e orari e dispongono di comode funzionalità di aggiornamento automatico.
Un'applicazione può modificare il comportamento di una proprietà specificando le opzioni della proprietà. Queste possono semplificare la convalida, impostare i valori predefiniti o modificare l'indicizzazione delle query.
Un modello può avere proprietà più complesse. Le proprietà ripetute sono simili a elenchi. Le proprietà strutturate sono simili a oggetti. Le proprietà calcolate di sola lettura vengono definite tramite funzioni, il che semplifica la definizione di una proprietà in termini di una o più altre proprietà. I modelli Expando possono definire le proprietà in modo dinamico.