Firestore in modalità Datastore (Datastore) supporta diversi tipi di dati per i valori delle proprietà. tra cui:
- Numeri interi
- Numeri in virgola mobile
- Stringhe
- Date
- Dati binari
Per un elenco completo dei tipi, vedi Proprietà e tipi di valori:
Proprietà e tipi di valore
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 i dati su una proprietà P ignoreranno le entità in cui P non è indicizzato). 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 a virgola fissa
- Numeri interi
- Date e ore
- Valori booleani
- Sequenze di byte
- Stringa Unicode
- Chiavi dell'archivio BLOB
- Numeri in virgola mobile
- Chiavi Datastore
Poiché le stringhe di testo lunghe e le stringhe di byte lunghe non sono indicizzate, non hanno un ordine definito.
Tipi di proprietà
NDB supporta i seguenti tipi di proprietà:
Tipo di proprietà | Descrizione |
---|---|
IntegerProperty | Numero intero a 64 bit con segno |
FloatProperty | Numero a virgola mobile a precisione doppia |
BooleanProperty | Booleano |
StringProperty | Stringa Unicode; fino a 1500 byte, indicizzati |
TextProperty | Stringa Unicode; lunghezza illimitata, non indicizzato |
BlobProperty | Stringa di byte non interpretata: se imposti indexed=True , fino a 1500 byte, indicizzati;se indexed è False (il valore predefinito), lunghezza illimitata, non indicizzata.Argomento facoltativo della parola chiave: compressed .
|
DateTimeProperty
| Data e ora (vedi Proprietà data e ora) |
DateProperty
| Data (vedi Proprietà data e ora) |
TimeProperty
| Ora (vedi Proprietà data e ora) |
GeoPtProperty
| Posizione geografica. Questo è un oggetto ndb.GeoPt .
L'oggetto
ha gli attributi lat e lon , entrambi di tipo float.
Puoi costruirne uno con due valori mobili,
ndb.GeoPt(52.37, 4.88)
o con una stringa ndb.GeoPt("52.37, 4.88") .
(Si tratta della stessa classe
db.GeoPt )
|
KeyProperty | Chiave Datastore Argomento facoltativo della parola chiave: kind=kind, per richiedere che le chiavi assegnate a questa proprietà abbiano sempre il tipo indicato. Può essere un o una sottoclasse del modello. |
BlobKeyProperty
| Chiave Blobstore Corrisponde a BlobReferenceProperty nella vecchia API di database, ma il valore della proprietà è un BlobKey anziché un BlobInfo ; puoi creare un BlobInfo utilizzando BlobInfo(blobkey)
|
UserProperty | Oggetto utente. |
StructuredProperty
| Include un tipo di modello all'interno di un altro, per valore (consulta 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 facoltativo della parola chiave: compressed .
|
PickleProperty
| Il valore è un oggetto Python (ad esempio un elenco, un dict o una stringa)
serializzabile usando il protocollo pickle di Python; Datastore
la serializzazione del sottaceto come blob. Non indicizzata per impostazione predefinita. Argomento parola chiave facoltativo: compressed .
|
GenericProperty | Valore generico Utilizzato principalmente dalla classe Expando
, ma utilizzabile anche in modo esplicito. Il tipo può essere uno dei seguenti:
int , long ,
float , bool , str ,
unicode , datetime , Key ,
BlobKey , GeoPt , User ,
None .
|
ComputedProperty
| Valore calcolato da altre proprietà da una funzione definita dall'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 su disco.
Occupa meno spazio, ma ha bisogno di CPU per la codifica/decodifica in fase di scrittura
operazioni di lettura.
Sia la compressione che la decompressione sono "lazy"; una proprietà compressa verrà decompresso solo la prima volta che vi accederai. Se leggi un'entità contenente un valore di proprietà compresso lo riscrivi senza accedere alla proprietà compressa, non sia decompresso e compresso. La strategia in contesto Cache partecipa a questo schema lazy, memcache archivia sempre il valore compresso per le proprietà compresse.
A causa del tempo di CPU aggiuntivo necessario per la compressione, di solito il è preferibile utilizzare proprietà compresse solo se i dati sono troppo grandi per farne a meno. Ricorda che la compressione basata su gzip solitamente 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 Nome datastore. Puoi utilizzare questa opzione per assegnare alla proprietà un nome diverso Datastore dal punto di vista dell'applicazione. Un utilizzo comune di questa funzionalità è ridurre lo spazio in Datastore, consentendo a Datastore di utilizzare nomi di proprietà abbreviati mentre il 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 della parola 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 riesce per questi motivi.Le proprietà non indicizzate costano meno operazioni di scrittura rispetto alle proprietà indicizzate. |
repeated | bool | False | Il valore della proprietà è un elenco Python contenente i valori del tipo sottostante
(consulta la sezione Proprietà ripetute). Non può essere combinato con required=True o default=True .
|
required | bool | False | È necessario specificare un valore per la proprietà. |
default | Tipo sottostante della proprietà | Nessuno | Valore predefinito della proprietà se non è specificato esplicitamente. |
choices | Elenco di valori del tipo sottostante | None | Elenco facoltativo dei valori consentiti. |
validator | Funzione | None | Funzione facoltativa per convalidare ed eventualmente forzare il valore. Verrà chiamata con argomenti
(prop, value) e dovrebbe restituire il valore
valore (possibilmente forzato) o sollevare un'eccezione. Richiamo della funzione
su un valore forzato non dovrebbe modificare ulteriormente il valore.
Ad esempio, è consentito restituire |
verbose_name | string | None
| Etichetta HTML facoltativa da utilizzare nei 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 vedere più valori per una proprietà di questo tipo. Per ogni valore viene creato un record dell'indice separato. Questo influisce sulla semantica delle query. Per un esempio, consulta Eseguire query per proprietà ripetute.
In questo esempio viene utilizzata una proprietà ripetuta:
...
Viene creata un'entità Datastore con i seguenti contenuti:
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.
Quando assegni un nuovo elenco, i tipi di elementi dell'elenco vengono
convalidato 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à convalidato quando scrivi l'entità in Datastore.
Datastore conserva l'ordine degli elementi dell'elenco in un ambiente , in modo da poter assegnare un significato al loro ordinamento.
Proprietà di data e ora
Sono disponibili tre tipi di proprietà per l'archiviazione di dati valori:
DateProperty
TimeProperty
DateTimeProperty
Questi valori appartengono alle classi corrispondenti
(date
, time
, datetime
)
del modulo datetime
di Python standard.
Il più generale dei tre è DateTimeProperty
,
che indica sia una data di 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 dipendere da questa relazione di ereditarietà,
(nota che differisce dalle relazioni di ereditarietà tra
le classi sottostanti definite dal modulo datetime
stesso).
Nota:
le ore dell'orologio di App Engine sono sempre espresse nel fuso orario
universale coordinato (UTC). Questo diventa rilevante se utilizzi la data o l'ora corrente
(datetime.datetime.now()
) come valore o esegui la conversione tra
oggetti DateTime e timestamp o tuple di tempo POSIX.
Tuttavia, in Datastore non vengono archiviate informazioni esplicite sul fuso orario,
quindi, se fai attenzione, puoi usarli per rappresentare l'ora locale
in qualsiasi fuso orario, se utilizzi l'ora corrente o le conversioni.
Ciascuna 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, usa
auto_now .
|
auto_now
| Imposta la proprietà sulla data/ora corrente quando l'entità viene creata e ogni volta che viene aggiornata. |
Queste opzioni non possono essere combinate con
repeated=True
.
Per entrambi l'impostazione predefinita è False
.
Se entrambi sono impostati su True
, auto_now
ha la precedenza.
È possibile sostituire 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.
Nota:
quando una transazione che scrive una proprietà conauto_now_add=True
non va a buon fine e viene riprovata in un secondo momento, verrà riutilizzato lo stesso valore di tempo del tentativo originale anziché aggiornarlo al momento del nuovo tentativo. Se la transazione non riesce definitivamente, il valore della proprietà sarà comunque impostato nella copia in memoria dell'entità.
Strutture
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:
...
...
Viene creata una singola entità Datastore con le seguenti proprietà:
La lettura di un'entità di questo tipo consente di ricostruire esattamente l'entità Contact
originale.
Sebbene le istanze Address
siano definite
utilizzando la stessa sintassi dei classi di modelli,
non sono entità complete.
Non hanno chiavi proprie in Datastore.
Non possono essere recuperate indipendentemente da Contact
l'entità alla quale appartengono.
Un'applicazione può, tuttavia, interrogare i valori dei propri
singoli campi; vedi
Filtro dei valori delle proprietà strutturate.
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 genera l'elenco corrispondente di istanze Address
.
Puoi specificare la consueta
opzioni proprietà
per le proprietà strutturate
(tranne indexed
). Il nome Datastore è
secondo argomento posizionale in questo caso
(la prima è la classe del modello utilizzata per definire la sottostruttura).
Se non devi eseguire query sulle 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 verrà memorizzata come segue:
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.
Nota:
Un StructuredProperty
con una proprietà nidificata (indipendentemente dal fatto che sia strutturata o meno)
supporta un solo livello di proprietà ripetute. StructuredProperty
può essere ripetuto o la proprietà nidificata può essere ripetuta, ma non entrambe. Una soluzione alternativa consiste nell'utilizzare
LocalStructuredProperty
, che non ha questo vincolo (ma non consente
query sui valori delle sue proprietà).
Proprietà calcolate
Le proprietà calcolate (ComputedProperty
) sono proprietà di sola lettura il cui valore viene calcolato da altri valori delle 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 sottoposto a query e visualizzato nello visualizzatore di Datastore, ma il valore archiviato viene ignorato quando l'entità viene letta nuovamente da Datastore. Il valore viene invece ricalcolato chiamando la funzione ogni volta che viene richiesto. Ad esempio:
...
Viene memorizzata un'entità con i seguenti valori di proprietà:
Se cambiamo il nome in "Nickie" e chiedi il valore
name_lower
, restituisce "nickie":
Nota:
utilizza ComputedProperty
se l'applicazione
esegue query per il valore calcolato. Se vuoi solo
utilizzare la versione derivata nel codice Python, definisci un metodo normale
o utilizza la funzione @property
integrata di Python.
Nota:
se crei un modello senza una chiave specificata manualmente e ti affidi a Datastore per
generare automaticamente l'ID dell'entità, nella prima put()
un ComputedProperty
non potrà leggere il campo ID poiché viene calcolato prima della generazione dell'ID.
Se hai bisogno di un elemento ComputedProperty
che utilizza l'ID dell'entità, puoi utilizzare il metodo
allocate_ids
per generare un ID e una chiave con cui creare l'entità, in modo che
ComputedProperty
potrà fare riferimento a quell'ID sulla prima funzione put() dell'entità.
Proprietà dei messaggi RPC del protocollo Google
La libreria Google Protocol RPC utilizza
Message
oggetti per i dati strutturati; possono rappresentare
richieste, risposte RPC o altro. NDB fornisce un'API per l'archiviazione
Gli oggetti RPC Message
del protocollo Google come proprietà delle entità.
Supponi di definire una sottoclasse Message
:
...
Puoi archiviare Note
oggetti in Datastore come entità
dei valori delle proprietà usando l'API msgprop
di NDB.
...
...
Se vuoi eseguire query sui nomi dei campi, questi devono essere indicizzati.
Puoi specificare un elenco di nomi di campi che verranno indicizzati con
il parametro indexed_fields
su MessageProperty
.
MessageProperty
supporta molte, ma non tutte, le
opzioni della proprietà. Supporta:
name
repeated
required
default
choices
validator
verbose_name
Le proprietà dei messaggi non supportano l'opzione della proprietà indexed
;
non puoi indicizzare i valori Message
. (puoi indicizzare campi di
un messaggio come descritto sopra.
Funzionano anche i messaggi nidificati (con MessageField
):
...
MessageProperty
ha un'opzione di proprietà speciale,
protocol
, che specifica in che modo l'oggetto messaggio viene
serializzato in Datastore. La
i valori sono nomi di protocollo utilizzati da protorpc.remote.Protocols
. I nomi dei protocolli supportati sono protobuf
e protojson
; il valore predefinito è protobuf
.
msgprop
definisce anche EnumProperty
, una proprietà
che può essere utilizzato per archiviare un protorpc.messages.Enum
in un'entità. Esempio:
...
...
EnumProperty
memorizza il valore come numero intero, di fatto,
EnumProperty
è una sottoclasse di IntegerProperty
.
Ciò implica che puoi rinominare i valori enum senza dover modificare
entità già archiviate, ma non è possibile rinumerarle.
La proprietà EnumProperty supporta le seguenti opzioni di proprietà:
name
indexed
repeated
required
default
choices
validator
verbose_name
Informazioni sui modelli di entità NDB
Un modello di entità NDB può definire le proprietà. Le proprietà delle entità sono un po' come i membri dei dati delle classi Python, un modo strutturato di conservare i dati; sono anche un po' come campi in una lo schema del database.
Un'applicazione tipica definisce un modello di dati definendo una classe che eredita da Model
con alcuni attributi della classe di proprietà.
Ad esempio,
...
Qui, username
, userid
e
email
sono proprietà di Account
.
Esistono molti altri tipi di proprietà. Alcuni sono utili per rappresentare date e ore e dispongono di comode funzionalità di aggiornamento automatico.
Un'applicazione può modificare il comportamento di una proprietà specificandovi opzioni che 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 un elenco. Le proprietà strutturate sono simili agli oggetti. Le proprietà calcolate di sola lettura vengono definite tramite le funzioni; e questo rende è facile definire una proprietà in termini di una o più altre proprietà. I modelli Expando possono definire le proprietà in modo dinamico.