Classe modello NDB

Una classe che eredita dalla classe Model rappresenta la struttura delle entità archiviate in Datastore. Le applicazioni definiscono le classi di modello per indicare la struttura delle loro entità, quindi creano un'istanza per queste classi di modello per creare entità. Tutte le classi devono ereditare (direttamente o indirettamente) dal modello.

In questa pagina è disponibile 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 del modello devono ereditare (direttamente o indirettamente) da Model. È possibile utilizzare assegnazioni semplici nella definizione della classe del 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 in 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à, è sufficiente modificarne gli attributi e riscriverla (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 valore predefinito e altro ancora. Esistono molti tipi di proprietà diversi.

Normalmente, kind è uguale al nome della classe (escluso 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 dovrebbe definire due classi di modelli con lo stesso tipo, anche se risiedono in moduli diversi. I tipi di un'applicazione sono considerati uno "spazio dei nomi" globale.

Le sottoclassi Model possono definire hook pre e post-chiamata per la maggior parte delle operazioni (get, put, delete, allo allo_id).

Costruttore

Un'applicazione in genere non chiama Model(), ma è probabile che chiami il costruttore di una classe che eredita da Model. In questo modo viene creata una nuova istanza del modello, nota anche come entità.

L'entità appena creata non viene scritta automaticamente in Datastore. A questo scopo, deve essere scritto in Datastore utilizzando una chiamata esplicita a put().

Argomenti:

Model sottoclassi supportano i seguenti argomenti delle parole chiave:

chiave
Istanza chiave per questo modello. Se viene utilizzato il parametro key, id e parent devono essere None (valore predefinito).
id
ID chiave per questo modello. Se si utilizza id, la chiave deve essere None (valore predefinito).
parent
Istanza chiave per il modello padre o None per uno di primo livello. Se viene utilizzato parent, il valore di key deve essere None.
spazio dei nomi
Spazio dei nomi da usare per questa entità oppure None (predefinito) per utilizzare lo spazio dei nomi attuale. Se viene utilizzato namespace, il valore di key deve essere None.

Un'applicazione può anche utilizzare gli argomenti delle parole chiave mappati alle proprietà del modello. Ad esempio, funziona come 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 una chiamata costruttore o populate(), viene impostata la chiave dell'entità, non un attributo della proprietà denominato "chiave".

Nota: se esegui l'override del costruttore in una sottoclasse del modello, assicurati che, in alcuni casi, il costruttore venga chiamato anche implicitamente e assicurati di supportare queste chiamate. Quando un'entità viene letta dal Datastore, viene creata innanzitutto 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 un secondo momento.

Metodi della classe

allocate_ids(size=Nessuno, max=Nessuno, parent=Nessuno, **ctx_options)

Consente di allocare un intervallo di ID chiave per questa classe di modello.

Argomenti

size [taglia]
Numero di ID da assegnare. È possibile specificare size o max, non entrambi.
max
ID massimo da allocare. È possibile specificare size o max, non entrambi.
parent
Chiave padre per la quale verranno assegnati 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 (inclusi).

get_by_id(id, parent=Nessuno, app=Nessuna, namespace=Nessuno, **ctx_options)
Restituisci un'entità per ID. Questa è solo una forma breve di Key(cls, id).get().

Argomenti

id
Un ID chiave di tipo stringa o intero.
parent
Chiave padre del modello da ottenere.
app (argomento parola chiave)
ID dell'app. Se non specificato, vengono richiesti i dati relativi all'app corrente.
namespace (argo 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 di modello o None se non trovata.

get_by_id_async(id, parent=Nessuno, app=Nessuna, namespace=Nessuno, **ctx_options)
Versione asincrona di get_by_id.

Restituisce un oggetto Future il cui risultato è un'istanza del modello o None se non trovato.

get_or_insert(key_name, parent=None, app=None, namespace=None, context_options=None, **constructor_args)
Recupera dal punto di vista transazionale un'entità esistente o ne crea una nuova.

Argomenti

key_name
Un nome di 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, vengono richiesti i dati relativi all'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 accetta 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 l'elemento key_name e l'elemento padre, questi argomenti verranno ignorati.

Restituisce l'istanza esistente della classe Model con il nome e l'elemento padre della chiave specificati o una nuova istanza appena creata.

Questa funzione utilizza una transazione. Se il codice che chiama questa funzione è già in una transazione, la 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 della classe Model con il nome e il padre della chiave specificati o una nuova istanza appena creata.

query([filter1, filter2, ...,] ancestor=None, app=None, namespace=None, filtri=Nessuno, 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 parola chiave distinct è un'abbreviazione di group_by = proiezione. Tutti gli altri argomenti delle parole chiave vengono passati al costruttore di query.

Gli argomenti posizionali vengono utilizzati per impostare i filtri iniziali.

Restituisce un oggetto Query.

Metodi di istanza

compila(**constructor_options)

Imposta i valori delle proprietà dell'entità. I suoi argomenti delle parole chiave riconoscono automaticamente i nomi delle proprietà, proprio come fa il costruttore.

put(**ctx_options)

Scrive i dati dell'entità in Datastore. Restituisce la chiave dell'entità.

Argomenti

**ctx_options
Opzioni di contesto
put_async(**ctx_options)

Scrive i dati dell'entità in modo asincrono nel Datastore. Restituisce un oggetto Future. Il risultato dell'oggetto Future sarà la chiave dell'entità.

Argomenti

**ctx_options
Opzioni di contesto
to_dict(include=all, excluded=None)

Restituisce un dict contenente i valori delle proprietà del modello. I valori delle proprietà per StructuredProperty e LocalStructuredProperty vengono convertiti in modo ricorsivo in dizionari.

Argomenti:

Includi
Elenco facoltativo di strutture da includere. Valore predefinito: tutti.
escludi
Elenco facoltativo di proprietà da escludere. Se c'è sovrapposizione tra include ed escludi, escludi le "vincite".

Nota: se il valore di una proprietà è un oggetto modificabile (ad es. un elenco che rappresenta una proprietà ripetuta oppure un dict o un elenco memorizzato in JsonProperty), a meno che il valore non venga convertito esplicitamente (ad es. nel caso di StructuredProperty), lo stesso oggetto viene restituito nel ditto archiviato nell'entità. In questi casi, la mutazione del dizionario cambia l'entità e viceversa.

Dati istanza

chiave
Proprietà speciale per archiviare la chiave del modello.

Metodi con gancio

La sottoclasse 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 consigli sulla scrittura di funzioni hook, consulta la pagina relativa agli hook del modello.

@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, key)
Hook eseguito prima del giorno delete()
@classmethod
_post_delete_hook(cls, key, futuro)
Hook eseguito dopo delete()
@classmethod
_pre_get_hook(cls, key)
Hook eseguito prima del giorno Key.get() quando si ottiene un'entità di questo modello.
@classmethod
_post_get_hook(cls, key, futuro)
Hook eseguito dopo Key.get() durante il recupero di un'entità di questo modello.
_pre_put_hook(self)
Hook eseguito prima del giorno put()
_post_put_hook(se stesso, futuro)
Hook eseguito dopo put()

Introspezione

Puoi usare questi metodi per esaminare le proprietà e la configurazione di un determinato modello. È utile se stai scrivendo una libreria o funzione che accetta più tipi di modelli.

Cerca per tipo

Ogni modello ha un kind che corrisponde in genere al nome della classe, a meno che non venga eseguito l'override. 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 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 di espansione.

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 esaminate. 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 del metodo

Tutti i metodi nella classe Model hanno un alias con 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 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 _.