Una classe che eredita dalla classe Model rappresenta la
struttura delle entità archiviate nel datastore.
Le applicazioni definiscono le classi di modelli per indicare la struttura delle loro entità, quindi istanziano queste classi di modelli per creare entità.
Tutte le classi di modelli devono ereditare (direttamente o indirettamente) da Model.
Questa pagina contiene la documentazione di riferimento dell'API. Per una panoramica, consulta Entità e chiavi NDB.
Introduzione
Una classe che eredita da Model
descrive le entità Datastore.
Tutte le classi di modelli devono ereditare (direttamente o indirettamente) da
Model.
Assegnazioni semplici nella
definizione della classe del modello possono essere utilizzate 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 in Datastore:
p = Person(name='Arthur Dent', age=42) k = p.put()
Il valore restituito da put() è una
Key, 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 relativi 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 dei campi da archiviare in Datastore, se devono essere indicizzati, il loro valore predefinito e altro ancora. Esistono molti tipi di proprietà diversi.
Il tipo è normalmente uguale al nome della classe (escluso il nome del modulo o qualsiasi altro ambito padre). Per ignorare il tipo (utile
per le modifiche allo schema),
definisci un metodo di 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 si trovano in moduli diversi. I tipi di un'applicazione sono considerati uno "spazio dei nomi" globale.
Le sottoclassi Model
possono definire hook pre-chiamata e post-chiamata
per la maggior parte delle operazioni
(get, put, delete, allocate_ids).
Costruttore
Normalmente, un'applicazione non chiama Model(), ma è probabile
che chiami il costruttore di una classe che eredita da Model.
Viene creata una nuova istanza di questo modello, nota anche come entità.
L'entità appena creata non viene scritta automaticamente in Datastore.
Per farlo, deve essere scritto in Datastore utilizzando una chiamata
esplicita a put().
Argomenti:
Le sottoclassi Model supportano questi argomenti delle parole chiave:
- chiave Istanza Key
- per questo modello. Se viene utilizzato il parametro
key,ideparentdevono essereNone(valore predefinito). - id
- ID chiave per questo modello. Se viene utilizzato
id, la chiave deve essereNone(il valore predefinito). - genitore
- Key instance per il modello principale o
Noneper uno di primo livello. Se viene utilizzatoparent,keydeve essereNone. - namespace
- Spazio dei nomi da utilizzare
per questa entità oppure
None(impostazione predefinita) per utilizzare lo spazio dei nomi corrente. Se viene utilizzatonamespace,keydeve essereNone.
Un'applicazione può anche utilizzare il mapping degli argomenti parola 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
"namespace".
Se passi, ad esempio, key="foo" in un costruttore o
nella 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
il costruttore viene chiamato anche implicitamente in alcuni casi 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é la chiave e i valori delle 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 un secondo momento.
Metodi della classe
- allocate_ids(size=None, max=None, parent=None, **ctx_options)
-
Alloca un intervallo di ID chiave per questa classe di modello.
Argomenti
- size
- Numero di ID da allocare. Puoi specificare
sizeomax, ma non entrambi. - max
- ID massimo da allocare. Puoi specificare
sizeomax, ma non entrambi. - genitore
- Chiave principale per cui verranno allocati gli ID.
- **ctx_options
- Opzioni contestuali
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
Futureil cui risultato è una tupla con (start, end) per l'intervallo allocato, inclusi. - get_by_id(id, parent=None, app=None, namespace=None, **ctx_options)
- Restituisce un'entità in base all'ID. Si tratta semplicemente di un'abbreviazione di
Key(cls, id).get().Argomenti
- id
- ID chiave stringa o intero.
- genitore
- Chiave principale del modello da recuperare.
- app (argomento parola chiave)
- ID dell'app. Se non specificato, vengono recuperati i dati dell'app corrente.
- namespace (argomento parola chiave)
- Namespace. Se non specificato, recupera i dati per lo spazio dei nomi predefinito.
- **ctx_options
- Opzioni contestuali
Restituisce un'istanza del modello o
Nonese non viene trovata. - get_by_id_async(id, parent=None, app=None, namespace=None, **ctx_options)
- Versione asincrona di get_by_id.
Restituisce un oggetto
Futureil cui risultato è un'istanza del modello oNonese non viene trovata. - get_or_insert(key_name, parent=None, app=None, namespace=None, context_options=None, **constructor_args)
- Recupera in modo transazionale un'entità esistente o ne crea una nuova.
Argomenti
- key_name
- Un nome di chiave (ovvero un ID chiave stringa) da recuperare o creare.
- genitore
- Chiave dell'entità padre, se presente.
- app
- ID dell'app. Se non specificato, vengono recuperati i dati dell'app corrente.
- namespace
- Namespace. Se non specificato, recupera i dati per lo spazio dei nomi predefinito.
- context_options
- Opzioni contestuali
Questa funzione accetta anche argomenti parola 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
key_namee il genitore forniti, questi argomenti verranno ignorati.Restituisce l'istanza esistente della classe
Modelcon il nome della chiave specificato e il genitore o una nuova 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
Futureil cui risultato è un'istanza esistente della classeModelcon il nome della chiave e il parent specificati o una nuova 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
Queryper questa classe, come descritto in Query.L'argomento della parola chiave
distinctè l'abbreviazione di group_by = projection. Tutti gli altri argomenti delle parole chiave vengono passati al costruttore di query.Se vengono forniti argomenti posizionali, questi vengono utilizzati per configurare i filtri iniziali.
Restituisce un oggetto
Query.
Metodi dell'istanza
- populate(**constructor_options)
-
Imposta i valori delle proprietà dell'entità. I relativi argomenti con parole chiave riconoscono automaticamente i nomi delle proprietà nello stesso modo in cui lo fa il costruttore.
- put(**ctx_options)
-
Scrive i dati dell'entità in Datastore. Restituisce la chiave dell'entità.
Argomenti
- **ctx_options
- Opzioni contestuali
- put_async(**ctx_options)
-
Scrive in modo asincrono i dati dell'entità in Datastore. Restituisce un oggetto
Future. Il risultato dell'oggettoFuturesarà la chiave dell'entità.Argomenti
- **ctx_options
- Opzioni contestuali
- to_dict(include=all, exclude=None)
-
Restituisce un
dictcontenente i valori delle proprietà del modello. I valori delle proprietà perStructuredPropertyeLocalStructuredPropertyvengono convertiti in modo ricorsivo in dizionari.Argomenti:
- include
- Elenco facoltativo di proprietà da includere. Valore predefinito: tutti.
- exclude
- Elenco facoltativo di proprietà da escludere. Se esiste una sovrapposizione tra inclusione ed esclusione, allora "vince" l'esclusione.
Nota: se un valore di proprietà è un oggetto modificabile (ad es. un elenco che rappresenta una proprietà ripetuta o un dizionario o un elenco memorizzato in un
JsonProperty), a meno che il valore non venga convertito esplicitamente (ad es. nel caso di unStructuredProperty), viene restituito lo stesso oggetto nel dizionario memorizzato nell'entità. In questi casi, la modifica del dizionario modificherà l'entità e viceversa.
Dati dell'istanza
- chiave
- Proprietà speciale per archiviare la chiave del modello.
Metodi di hook
La sottoclasse di Model di un'applicazione può definire
uno o più di questi metodi come metodi "hook" pre o post-operazione.
Ad esempio, per eseguire del codice prima di ogni "get", definisci il metodo _pre_get_hook() della sottoclasse del modello. Per suggerimenti sulla scrittura di funzioni hook,
consulta Hook del modello.
- @classmethod
_pre_allocate_ids_hook(cls, size, max, parent) - Hook eseguito prima
allocate_ids() - @classmethod
_post_allocate_ids_hook(cls, size, max, parent, future) - Hook eseguito dopo
allocate_ids() - @classmethod
_pre_delete_hook(cls, key) - Hook eseguito prima
delete() - @classmethod
_post_delete_hook(cls, key, future) - Hook eseguito dopo
delete() - @classmethod
_pre_get_hook(cls, key) - Hook eseguito prima di
Key.get()quando viene recuperata un'entità di questo modello. - @classmethod
_post_get_hook(cls, key, future) - Hook eseguito dopo
Key.get()durante il recupero di un'entità di questo modello. - _pre_put_hook(self)
- Hook eseguito prima
put() - _post_put_hook(self, future)
- Hook eseguito dopo
put()
Introspezione
Puoi utilizzare questi metodi per esaminare le proprietà e la configurazione di un determinato modello. Questa opzione è utile se stai scrivendo una libreria o una funzione che accetta più tipi di modelli.
Ricerca per tipo
Ogni modello ha un tipo che di solito corrisponde al nome della classe, a meno che non sia
sovrascritto. 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 modelli già 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 Expando.
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)}
È possibile eseguire l'introspezione delle istanze della proprietà. Le
opzioni fornite al costruttore
sono disponibili come proprietà con il 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 dei metodi
Ogni metodo della classe Model ha un alias con il prefisso _. Ad esempio,
_put() equivale 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 il 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 crei librerie di terze parti che interagiscono con modelli arbitrari,
è consigliabile utilizzare i metodi con il prefisso _.