Una classe che eredita dalla classe Model
rappresenta la
struttura delle entità archiviate in Datastore.
Le applicazioni definiscono le classi dei modelli per indicare la struttura delle loro entità, quindi creano un'istanza di queste classi per creare le entità.
Tutte le classi del modello devono ereditare (direttamente o indirettamente) dal modello.
Questa pagina ha la documentazione di riferimento dell'API. Per una panoramica, consulta la sezione Entità e chiavi NDB.
Introduzione
Una classe che eredita da Model
descrive le entità Datastore.
Tutte le classi di modello devono ereditare (direttamente o indirettamente) da Model
.
È possibile utilizzare assegnazioni semplici nella definizione della classe modello per dichiarare la struttura del modello:
from google.appengine.ext import ndb class Person(ndb.Model): name = ndb.StringProperty() age = ndb.IntegerProperty()
Ora possiamo creare un'entità Person e scriverla nel Datastore:
p = Person(name='Arthur Dent', age=42) k = p.put()
Il valore restituito da put()
è una
chiave, che può essere utilizzata per recuperare la stessa entità
in un secondo momento:
p2 = k.get() p2 == p # Returns True
Per aggiornare un'entità, modifica semplicemente i suoi attributi e riscrivila (tieni presente che la chiave non viene modificata):
p2.name = 'Arthur Philip Dent' p2.put()
Possiamo anche eliminare un'entità (utilizzando la chiave):
k.delete()
Le definizioni delle proprietà nel corpo della classe indicano al sistema i nomi e i tipi di campi da archiviare in Datastore, se devono essere indicizzati, il loro valore predefinito e altro ancora. Esistono molti tipi di proprietà diversi.
kind è di solito uguale al nome della classe (esclusi il nome del modulo o qualsiasi altro ambito padre). Per eseguire l'override del tipo (utile per le modifiche allo schema), definisci un metodo della classe denominato _get_kind()
, come segue:
class MyModel(ndb.Model): @classmethod def _get_kind(cls): return 'AnotherKind'
Un'applicazione non deve definire due classi di modelli dello stesso tipo, anche se risiedono in moduli diversi. I tipi di un'applicazione sono considerati uno "spazio dei nomi" globale.
Le sottoclassi di Model
possono definire hook pre-chiamata e post-chiamata per la maggior parte delle operazioni
(get, put, delete, alloca_id).
Costruttore
Un'applicazione di solito non chiama Model()
, ma è probabile che chiami il costruttore di una classe che eredita da Model
.
Viene creata una nuova istanza del modello, nota anche come entità.
L'entità appena creata non viene scritta automaticamente nel datastore.
A tale scopo, deve essere scritto in Datastore utilizzando una chiamata esplicita a put()
.
Argomenti:
Model
sottoclassi supportano i seguenti argomenti parola chiave:
- chiave
- Istanza chiave per questo modello. Se viene utilizzato il
parametro
key
,id
eparent
devono essereNone
(valore predefinito). - id
- ID chiave del modello. Se viene utilizzato
id
, la chiave deve essereNone
(valore predefinito). - parent
- Istanza chiave per il modello principale o
None
per uno di primo livello. Se viene utilizzatoparent
,key
deve essereNone
. - spazio dei nomi
- Spazio dei nomi da utilizzare per questa entità o
None
(predefinito) per utilizzare lo spazio dei nomi attuale. Se viene utilizzatonamespace
,key
deve essereNone
.
Un'applicazione può anche utilizzare la mappatura degli argomenti delle parole chiave alle proprietà del modello. Ad esempio, funziona quanto segue:
class Person(ndb.Model): name = StringProperty() age = IntegerProperty() p = Person(name='Arthur Dent', age=42)
Non puoi definire facilmente una proprietà denominata "key", "id", "parent" o "spazio dei nomi".
Se passi, ad esempio, key="foo"
in un costruttore o in una chiamata populate()
, viene impostata la chiave dell'entità, non un attributo della proprietà denominato "key".
Nota:
se esegui l'override del costruttore in una sottoclasse Model, tieni presente che in alcuni casi il costruttore viene anche chiamato implicitamente e assicurati di supportare queste chiamate. Quando un'entità viene letta da Datastore, viene prima creata un'entità vuota chiamando il costruttore senza argomenti, dopodiché i valori della chiave e della proprietà vengono impostati uno alla volta.
Quando get_or_insert()
o get_or_insert_async()
crea una nuova istanza, passa
**constructor_args
al costruttore e imposta la chiave in seguito.
Metodi delle classi
- allocate_ids(size=Nessuno, max=Nessuno, parent=Nessuno, **ctx_options)
-
Alloca un intervallo di ID chiave per questa classe di modello.
Argomenti
- size [taglia]
- Numero di ID da allocare. È possibile specificare
size
omax
, non entrambi. - max
- ID massimo da allocare. È possibile specificare
size
omax
, non entrambi. - parent
- Chiave principale per la quale verranno allocati gli ID.
- **ctx_options
- Opzioni di contesto
Restituisce una tupla con (start, end) per l'intervallo allocato, inclusi.
Un'applicazione non può chiamare
allocate_ids()
in una transazione. - allocate_ids_async(size=None, max=None, parent=None, **ctx_options)
-
Versione asincrona di allocate_ids.
Restituisce un oggetto
Future
il cui risultato è una tupla con (start, end) per l'intervallo allocato, inclusivo. - get_by_id(id, parent=Nessuno, app=Nessuno, namespace=Nessuno, **ctx_options)
- Restituisci un'entità in base all'ID. Questo è in realtà solo un modo breve per
Key(cls, id).get()
.Argomenti
- id
- Una stringa o un ID chiave di un numero intero.
- parent
- Chiave padre del modello da ottenere.
- app (argomento della parola chiave)
- ID dell'app. Se non specificato, consente di recuperare i dati dell'app corrente.
- spazio dei nomi (argomento della parola chiave)
- Spazio dei nomi. Se non specificato, ottiene i dati per lo spazio dei nomi predefinito.
- **ctx_options
- Opzioni di contesto
Restituisce un'istanza del modello o
None
se non lo trovi. - get_by_id_async(id, parent=None, app=None, namespace=None, **ctx_options)
- Versione asincrona di get_by_id.
Restituisce un oggetto
Future
il cui risultato è un'istanza del modello oppureNone
se non lo trovi. - get_or_insert(key_name, parent=Nessuno, app=Nessuno, namespace=Nessuno, context_options=Nessuno, **constructor_args)
- Recupera un'entità esistente o ne crea una nuova.
Argomenti
- key_name
- Un nome della chiave (ovvero un ID chiave di stringa) da recuperare o creare.
- parent
- Chiave dell'entità padre, se presente.
- app
- ID dell'app. Se non specificato, consente di recuperare i dati dell'app corrente.
- spazio dei nomi
- Spazio dei nomi. Se non specificato, ottiene i dati per lo spazio dei nomi predefinito.
- context_options
- Opzioni di contesto
Questa funzione prende anche gli argomenti delle parole chiave da passare al costruttore della classe del modello se non esiste già un'istanza per il nome della chiave specificato. Se esiste già un'istanza con il valore
key_name
fornito e l'istanza padre, questi argomenti verranno eliminati.Restituisce l'istanza esistente della classe
Model
con il nome della chiave specificato e la classe padre o una nuova istanza appena creata.Questa funzione utilizza una transazione. Se il codice che chiama questa funzione è già in una transazione, questa funzione tenta di riutilizzare la transazione esistente. Se il gruppo di entità di questa funzione non è compatibile con la transazione esistente, può verificarsi un errore.
- get_or_insert_async(key_name, parent=None, app=None, namespace=None, context_options=None, **constructor_args)
-
Questa è la versione asincrona di get_or_insert.
Restituisce un oggetto
Future
il cui risultato è un'istanza esistente di una classeModel
con il nome della chiave specificata e l'oggetto padre o una nuova istanza appena creata. - query([filter1, filter2, ...,] ancestor=None, app=None, namespace=None, filters=None, orders=None, default_options=None, projection=None distinct=False group_by=None)
-
Crea un oggetto
Query
per questa classe come descritto in Query.L'argomento della parola chiave
distinct
è un'abbreviazione di group_by = proiezione. Tutti gli altri argomenti delle parole chiave vengono passati al costruttore della query.Se vengono forniti argomenti posizionali, vengono utilizzati per impostare i filtri iniziali.
Restituisce un oggetto
Query
.
Metodi di istanza
- compilazione(**constructor_options)
-
Imposta i valori delle proprietà dell'entità. Gli argomenti delle parole chiave riconoscono automaticamente i nomi delle proprietà così come fa il costruttore.
- put(**ctx_options)
-
Scrive i dati dell'entità nel Datastore. Restituisce la Chiave dell'entità.
Argomenti
- **ctx_options
- Opzioni di contesto
- put_async(**ctx_options)
-
Scrive in modo asincrono i dati dell'entità nel datastore. Restituisce un oggetto
Future
. Il risultato dell'oggettoFuture
sarà la chiave dell'entità.Argomenti
- **ctx_options
- Opzioni di contesto
- to_dict(include=all, exclude=Nessuno)
-
Restituisce un valore
dict
contenente i valori delle proprietà del modello. I valori delle proprietà perStructuredProperty
eLocalStructuredProperty
vengono convertiti ricorsivamente in dizionari.Argomenti:
- includi
- Elenco facoltativo di proprietà da includere. Predefinito: tutti.
- escludere
- Elenco facoltativo di proprietà da escludere. Se esiste una sovrapposizione tra includi ed escludi, escludi le "vittorie".
Nota: se il valore di una proprietà è un oggetto modificabile (ad esempio un elenco che rappresenta una proprietà ripetuta oppure un dict o un elenco archiviato in un
JsonProperty
), a meno che il valore non venga convertito esplicitamente (ad es. nel caso diStructuredProperty
), lo stesso oggetto viene restituito nel dict archiviato nell'entità. In questi casi, la modifica del dizionario comporterà la modifica dell'entità e viceversa.
Dati istanza
- chiave
- Proprietà speciale per l'archiviazione della chiave del modello.
Metodi con hook
La sottoclasse Model
di un'applicazione può definire uno o più di questi metodi come metodi "hook" prima o dopo l'operazione.
Ad esempio, per eseguire codice prima di ogni "get", definisci il metodo _pre_get_hook()
della sottoclasse del modello. Per consigli sulla scrittura delle funzioni di hook, consulta la sezione Modelli di hook.
- @classmethod
_pre_allocate_ids_hook(cls, size, max, parent) - Hook eseguito prima del giorno
allocate_ids()
- @classmethod
_post_allocate_ids_hook(cls, size, max, parent, future) - Hook eseguito dopo
allocate_ids()
- @classmethod
_pre_delete_hook(cls, chiave) - Hook eseguito prima del giorno
delete()
- @classmethod
_post_delete_hook(cls, key, future) - Hook eseguito dopo
delete()
- @classmethod
_pre_get_hook(cls, key) - Hook che viene eseguito prima di
Key.get()
quando si ottiene un'entità di questo modello. - @classmethod
_post_get_hook(cls, key, future) - Hook che viene eseguito dopo
Key.get()
quando si ottiene un'entità di questo modello. - _pre_put_hook(self)
- Hook eseguito prima del giorno
put()
- _post_put_hook(self, futuro)
- Hook eseguito dopo
put()
Introspezione
Puoi utilizzare questi metodi per esaminare le proprietà e la configurazione di un determinato modello. Ciò è utile se stai scrivendo una libreria o funzione che accetta più tipi di modelli.
Cerca per tipo
Ogni modello ha un valore kind che di solito corrisponde al nome della classe, a meno che non venga
ignorato. Puoi utilizzare il tipo per trovare la classe del modello associata utilizzando
_lookup_model
.
class Animal(ndb.Model): type = ndb.StringProperty() print Animal._get_kind() # 'Animal' print ndb.Model._lookup_model('Animal') # class Animal
Tieni presente che _lookup_model
funziona solo per le classi di modello che sono già state importate dall'applicazione.
Proprietà
Puoi ottenere un elenco di tutte le proprietà associate a un modello utilizzando _properties
.
class User(ndb.Model): name = ndb.StringProperty() email = ndb.StringProperty() print User._properties # {'email': StringProperty('email'), 'name': StringProperty('name')}
_properties
funziona anche per le istanze Growo.
class Example(ndb.Expando): pass e = Example() e.foo = 1 e.bar = 'blah' e.tags = ['exp', 'and', 'oh'] print e._properties # {'foo': GenericProperty('foo'), 'bar': GenericProperty('bar'), # 'tags': GenericProperty('tags', repeated=True)}
Le istanze della proprietà possono essere analizzate. Le
opzioni fornite al costruttore
sono disponibili come proprietà con prefisso _
.
print User._properties['email']._name # 'email' print User._properties['email']._required # False print User._properties['email']._default # None print User._properties['email']._choices # None print User._properties['email']._compressed # False print User._properties['email']._indexed # True print User._properties['email']._compressed # False print User._properties['email']._repeated # False print User._properties['email']._verbose_name # None print isinstance(User._properties['email'], ndb.StringProperty) # True
Alias di metodo
Ogni metodo nella classe Model
ha un alias con prefisso _
. Ad esempio, _put()
è equivalente a put()
. Ciò significa che puoi avere proprietà con nomi in conflitto con i nomi dei metodi, a condizione che utilizzi sempre i metodi con prefisso _
. Tuttavia, tieni presente che non puoi specificare proprietà denominate key
, parent
o id
nel costruttore.
class MyModel(ndb.Model): put = ndb.StringProperty() query = ndb.StringProperty() key = ndb.StringProperty() entity = MyModel() entity.put = '1' entity.query = '2' entity.key = '3' entity._put() print entity # MyModel(key=Key('MyModel', ...), put=u'1', query=u'2', key=u'3') print MyModel._query().fetch() # same as above.
Se stai creando librerie di terze parti che interagiscono con modelli arbitrari,
ti consigliamo di utilizzare i metodi con prefisso _
.