Eine Klasse, die der Model
-Klasse untergeordnet ist, stellt die Struktur der im Datenspeicher gespeicherten Entitäten dar.
Anwendungen definieren Modellklassen, um die Struktur ihrer Entitäten anzugeben. Diese Modellklassen werden dann zum Erstellen von Entitäten verwendet.
Alle Modellklassen müssen dem Modell (direkt oder indirekt) untergeordnet sein.
Sie finden auf dieser Seite die API-Referenzdokumentation. Eine Übersicht finden Sie unter NDB-Entitäten und -Schlüssel.
Einführung
Eine Klasse, die der Model
-Klasse untergeordnet ist, beschreibt Datenspeicherentitäten.
Alle Modellklassen müssen der Model
-Klasse (direkt oder indirekt) untergeordnet sein.
Einfache Zuweisungen in der Modellklassendefinition können dazu verwendet werden, die Struktur des Modells zu deklarieren:
from google.appengine.ext import ndb class Person(ndb.Model): name = ndb.StringProperty() age = ndb.IntegerProperty()
Sie können jetzt eine Personenentität erstellen und in den Datenspeicher schreiben:
p = Person(name='Arthur Dent', age=42) k = p.put()
Der Rückgabewert von put()
ist ein Schlüssel, mit dem dieselbe Entität später abgerufen werden kann:
p2 = k.get() p2 == p # Returns True
Wenn Sie ein Objekt aktualisieren möchten, ändern Sie einfach dessen Attribute und schreiben es zurück. Beachten Sie, dass der Schlüssel hierdurch nicht geändert wird.
p2.name = 'Arthur Philip Dent' p2.put()
Sie können auch eine Entität mit dem Schlüssel löschen:
k.delete()
Die Property-Definitionen im Klassentext teilen dem System die Namen und Typen der Felder mit, die im Datenspeicher gespeichert werden sollen, ob sie indexiert werden müssen sowie ihren Standardwert und weitere Informationen. Es gibt viele verschiedene Property-Typen.
Die Art entspricht normalerweise dem Klassennamen (ausschließlich des Modulnamens oder eines anderen übergeordneten Bereichs). Zum Überschreiben der Art (nützlich für Schemaänderungen), definieren Sie so eine Klassenmethode mit dem Namen _get_kind()
:
class MyModel(ndb.Model): @classmethod def _get_kind(cls): return 'AnotherKind'
Eine Anwendung darf nicht zwei Modellklassen derselben Art definieren, auch dann nicht, wenn sich die Modellklassen in unterschiedlichen Modulen befinden. Die Arten einer Anwendung werden als globaler "Namespace" betrachtet.
Abgeleitete Model
-Klassen können Hooks vor und nach dem Aufrufen der meisten Vorgänge definieren (get, put, delete, allocate_ids).
Konstruktor
Eine Anwendung ruft normalerweise nicht Model()
auf, ruft aber wahrscheinlich den Konstruktor einer Klasse ab, die Model
untergeordnet ist.
Hierdurch wird eine neue Instanz dieses Modells erstellt, die auch als Entität bezeichnet wird.
Die neu erstellte Entität wird nicht automatisch in den Datenspeicher geschrieben.
Sie muss mithilfe eines expliziten Aufrufs von put()
in den Datenspeicher geschrieben werden.
Argumente:
Model
- Unterklassen unterstützen diese Schlüsselwortargumente:
- key
- Schlüsselinstanz für dieses Modell. Wenn der Parameter
key
verwendet wird, müssenid
undparent
die StandardeinstellungNone
haben. - id
- Schlüssel-ID für dieses Modell. Wenn
id
verwendet wird, muss der Schlüssel die StandardeinstellungNone
haben. - parent
- Schlüsselinstanz für das übergeordnete Modell oder
None
für ein Modell auf oberster Ebene. Wennparent
verwendet wird, musskey
None
sein. - Namespace
- Namespace zur Verwendung für diese Entität oder die Standardeinstellung
None
, um den aktuellen Namespace zu verwenden. Wennnamespace
verwendet wird, musskey
None
sein.
Eine Anwendung kann auch Schlüsselwortargumente verwenden, die den Properties des Modells zugeordnet sind. Siehe folgendes Beispiel:
class Person(ndb.Model): name = StringProperty() age = IntegerProperty() p = Person(name='Arthur Dent', age=42)
Sie können nicht einfach eine Property namens "key", "id", "parent" oder "namespace" definieren.
Wenn Sie beispielsweise key="foo"
in einem Konstruktor oder populate()
-Aufruf übergeben, wird der Schlüssel der Entität festgelegt, nicht das Attribut "key".
Hinweis: Wenn Sie den Konstruktor in einer abgeleiteten Modellklasse überschreiben, wird der Konstruktor in einigen Fällen auch implizit aufgerufen. Sie müssen diese Aufrufe unterstützen. Beim Lesen einer Entität aus dem Datenspeicher wird zuerst eine leere Entität erstellt, indem der Konstruktor ohne Argumente aufgerufen wird. Anschließend werden die Schlüsselwerte und Attributwerte nacheinander festgelegt.
Wenn get_or_insert()
oder get_or_insert_async()
eine neue Instanz erstellt, wird **constructor_args an den Konstruktor übergeben. Anschließend wird der Schlüssel festgelegt.
Klassenmethoden
- allocate_ids(size=None, max=None, parent=None, **ctx_options)
-
Ordnet dieser Modellklasse einen Bereich von Schlüssel-IDs zu.
Argumente
- size
- Anzahl der zuzuweisenden IDs. Es kann entweder
size
odermax
angegeben werden, nicht beides. - Max
- Maximale zuzuweisende ID. Es kann entweder
size
odermax
angegeben werden, nicht beides. - parent
- Übergeordneter Schlüssel, für den die IDs zugewiesen werden.
- **ctx_options
- Kontextoptionen
Gibt ein Tupel mit (start, end) für den zugewiesenen Bereich zurück. Der Bereich ist einschließlich.
Eine Anwendung kann
allocate_ids()
in einer Transaktion nicht aufrufen. - allocate_ids_async(size=None, max=None, parent=None, **ctx_options)
-
Asynchrone Version von allocate_ids.
Gibt das Objekt
Future
zurück, dessen Ergebnis ein Tupel mit (start, end) für den zugewiesenen Bereich ist. Der Bereich ist einschließlich. - get_by_id(id, parent=None, app=None, namespace=None, **ctx_options)
- Gibt eine Entität nach ID zurück. Dies ist nur eine Abkürzung für
Key(cls, id).get()
.Argumente
- id
- Ein String oder eine Schlüssel-ID als Ganzzahl.
- parent
- Übergeordneter Schlüssel des abzurufenden Modells.
- app (Schlüsselwortargument)
- ID der App. Wenn nicht angegeben, werden Daten für die aktuelle App abgerufen.
- namespace (Schlüsselwortargument)
- Namespace. Wenn nicht angegeben, werden Daten für den Standard-Namespace abgerufen.
- **ctx_options
- Kontextoptionen
Gibt eine Modellinstanz zurück oder
None
, falls nicht gefunden. - get_by_id_async(id, parent=None, app=None, namespace=None, **ctx_options)
- Asynchrone Version von get_by_id.
Gibt ein
Future
-Objekt zurück, dessen Ergebnis eine Modellinstanz ist, oderNone
, wenn es nicht gefunden wird. - get_or_insert(key_name, parent=None, app=None, namespace=None, context_options=None, **constructor_args)
- Ruft eine vorhandene Entität transaktional ab oder erstellt eine neue Entität.
Argumente
- key_name
- Ein Schlüsselname (eine String-Schlüssel-ID) zum Abrufen oder Erstellen.
- parent
- Übergeordneter Entitätenschlüssel, falls vorhanden.
- app
- ID der App. Wenn nicht angegeben, werden Daten für die aktuelle App abgerufen.
- Namespace
- Namespace. Wenn nicht angegeben, werden Daten für den Standard-Namespace abgerufen.
- context_options
- Kontextoptionen
Diese Funktion übernimmt auch Schlüsselwortargumente, die an den Konstruktor der Modellklasse übergeben werden, wenn eine Instanz für den angegebenen Schlüsselnamen noch nicht vorhanden ist. Wenn eine Instanz mit dem angegebenen
key_name
und dem übergeordneten Element bereits vorhanden ist, werden diese Argumente verworfen.Gibt die vorhandene Instanz der
Model
-Klasse mit dem angegebenen Schlüsselnamen und dem übergeordneten Element oder eine neue Instanz zurück, die gerade erstellt wurde.Diese Funktion verwendet eine Transaktion. Wenn der Code, der diese Funktion aufruft, bereits in einer Transaktion vorhanden ist, versucht diese Funktion, die vorhandene Transaktion noch einmal zu verwenden. Wenn die Entitätengruppe dieser Funktion mit der vorhandenen Transaktion nicht kompatibel ist, kann dies zu einem Fehler führen.
- get_or_insert_async(key_name, parent=None, app=None, namespace=None, context_options=None, **constructor_args)
-
Dies ist die asynchrone Version von get_or_insert.
Gibt das Objekt
Future
zurück, dessen Ergebnis eine vorhandene Instanz derModel
-Klasse mit dem angegebenen Schlüsselnamen und dem übergeordneten Element oder eine neu erstellte Instanz ist. - query([filter1, filter2, ...,] ancestor=None, app=None, namespace=None, filters=None, orders=None, default_options=None, projection=None distinct=False group_by=None)
-
Erstellt ein
Query
-Objekt für diese Klasse, wie unter Abfragen beschrieben.Das Keyword-Argument
distinct
steht für group_by = projection. Alle anderen Schlüsselwortargumente werden an den Abfragekonstruktor übergeben.Wenn Positionsargumente vorgegeben sind, werden sie zum Einrichten anfänglicher Filter verwendet.
Gibt ein
Query
-Objekt zurück.
Instanzmethoden
- populate(**constructor_options)
-
Legt Werte für die Properties der Entität fest. Die zugehörigen Schlüsselwortargumente erkennen Property-Namen automatisch auf dieselbe Weise wie der Konstruktor.
- put(**ctx_options)
-
Schreibt die Daten der Entität in den Datenspeicher. Gibt den Schlüssel der Entität zurück.
Argumente
- **ctx_options
- Kontextoptionen
- put_async(**ctx_options)
-
Schreibt die Daten der Entität asynchron in den Datenspeicher. Gibt ein
Future
-Objekt zurück. Das Ergebnis desFuture
-Objekts ist der Schlüssel der Entität.Argumente
- **ctx_options
- Kontextoptionen
- to_dict(include=all, exclude=None)
-
Gibt ein
dict
zurück, das die Attributwerte des Modells enthält. Attributwerte fürStructuredProperty
undLocalStructuredProperty
werden rekursiv in Wörterbücher umgewandelt.Argumente:
- include
- Optionale Liste der einzuschließenden Properties. Standard: alle.
- exclude
- Optionale Liste der auszuschließenden Properties. Wenn es eine Überschneidung zwischen Einschließen und Ausschließen gibt, dann "gewinnt" Ausschließen.
Hinweis: Wenn ein Attributwert ein veränderbares Objekt ist (z. B. eine Liste, die ein wiederholtes Attribut darstellt, ein Wörterbuch oder eine Liste in einem
JsonProperty
) und der Wert nicht explizit umgewandelt wird (z. B. im Fall vonStructuredProperty
), wird im Wörterbuch das gleiche Objekt zurückgegeben, das in der Entität gespeichert ist. In solchen Fällen wird durch Mutieren des Wörterbuchs die Entität mutiert und umgekehrt.
Instanzdaten
- key
- Spezielles Attribut zum Speichern des Modellschlüssels.
Hook-Methoden
Die abgeleitete Model
-Klasse einer Anwendung kann eine oder mehrere dieser Methoden als "Hook"-Methoden vor oder nach dem Vorgang definieren.
Wenn Sie beispielsweise den gleichen Code vor jedem "get" ausführen möchten, definieren Sie die Methode _pre_get_hook()
der abgeleiteten Modellklasse. Hinweise zum Schreiben von Hook-Funktionen finden Sie unter Modell-Hooks.
- @classmethod
_pre_allocate_ids_hook(cls, size, max, parent) - Hook, der vor
allocate_ids()
ausgeführt wird - @classmethod
_post_allocate_ids_hook(cls, size, max, parent, future) - Hook, der nach
allocate_ids()
ausgeführt wird - @classmethod
_pre_delete_hook(cls, key) - Hook, der vor
delete()
ausgeführt wird - @classmethod
_post_delete_hook(cls, key, future) - Hook, der nach
delete()
ausgeführt wird - @classmethod
_pre_get_hook(cls, key) - Hook, der vor
Key.get()
ausgeführt wird, wenn eine Entität dieses Modells abgerufen wird. - @classmethod
_post_get_hook(cls, key, future) - Hook, der nach
Key.get()
ausgeführt wird, wenn eine Entität dieses Modells abgerufen wird. - _pre_put_hook(self)
- Hook, der vor
put()
ausgeführt wird - _post_put_hook(self, future)
- Hook, der nach
put()
ausgeführt wird
Introspektion
Sie können diese Methoden verwenden, um die Properties und die Konfiguration eines bestimmten Modells zu überprüfen. Dies ist nützlich, wenn Sie eine Bibliothek oder Funktion schreiben, die mehrere Typen von Modellen akzeptiert.
Nach Art suchen
Jedes Modell hat eine Art, die normalerweise dem Klassennamen entspricht, es sei denn, sie wird überschrieben. Sie können die Art verwenden, um die zugehörige Modellklasse mithilfe von _lookup_model
zu finden.
class Animal(ndb.Model): type = ndb.StringProperty() print Animal._get_kind() # 'Animal' print ndb.Model._lookup_model('Animal') # class Animal
Beachten Sie, dass _lookup_model
nur für Modellklassen funktioniert, die bereits von der Anwendung importiert wurden.
Eigenschaften
Mit _properties
können Sie eine Liste aller mit einem Modell verknüpften Attribute abrufen.
class User(ndb.Model): name = ndb.StringProperty() email = ndb.StringProperty() print User._properties # {'email': StringProperty('email'), 'name': StringProperty('name')}
_properties
funktioniert auch für Expando-Instanzen.
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)}
Attributinstanzen können auch einer Introspektion unterzogen werden. Die dem Konstruktor bereitgestellten Optionen sind als Attribute mit dem Präfix _
verfügbar.
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
Methodenaliasse
Jede Methode in der Klasse Model
hat ein Alias mit dem Präfix _
. _put()
entspricht beispielsweise put()
. Dies bedeutet, dass Attribute mit Namen vorhanden sein können, die mit Methodennamen in Konflikt stehen. Dies setzt jedoch voraus, dass Sie die Methoden immer mit dem Präfix _
verwenden. Beachten Sie jedoch, dass Sie keine Eigenschaften mit dem Namen key
, parent
oder id
im Konstruktor angeben können.
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.
Wenn Sie Bibliotheken von Drittanbietern erstellen, die mit beliebigen Modellen interagieren, wird die Verwendung der Methoden mit dem Präfix _
empfohlen.