Sie müssen eine Modellklasse für Ihre Entität erstellen. Dafür haben Sie die folgenden beiden Möglichkeiten:
- Eine Modellklasse erstellen, die Entitäts-Properties definiert.
- Eine Expando-Modellklasse erstellen, die keine Entitäten im Voraus definiert.
In diesem Dokument wird gezeigt, wie Sie diese beiden Arten von Modellklassen erstellen.
Es wird dabei auch erläutert, wie Sie einen Modell-Hook erstellen, mit dem Ihre Anwendung vor oder nach bestimmten Vorgängen, z. B. vor jeder get()
-Methode, Code ausführen kann.
Modellklassen mit Attributen erstellen
Bevor Sie eine Entität erstellen, müssen Sie eine Modellklasse anlegen, die eine oder mehrere Entitätsattribute definiert. Beispiel:
...
Dabei soll jede Konten-Entität Properties für den Nutzernamen, die Nutzer-ID und die E-Mail-Adresse haben.
Eine vollständige Liste der Property-Typen finden Sie in der Referenz zu Entitäts-Properties.
Expando-Modellklassen erstellen
Sie müssen keine Modellklassen verwenden, die Attribute im Voraus definieren.
Eine spezielle abgeleitete Modellklasse mit dem Namen Expando
ändert das Verhalten ihrer Entitäten, sodass alle zugewiesenen Attribute im Datenspeicher abgelegt werden. Beachten Sie, dass solche Attribute nicht mit einem Unterstrich beginnen dürfen.
So erstellen Sie ein Expando-Modell:
...
Damit wird eine Entität mit einem foo
-Attribut und dessen ganzzahligen Wert 1
, mit einem bar
-Attribut und dessen Stringwert 'blah'
sowie mit einem wiederholten tag
-Attribut und dessen Stringwerten 'exp'
, 'and'
und 'oh'
in den Datenspeicher geschrieben.
Die Attribute werden indexiert und können mit dem Attribut _properties
der Entität überprüft werden:
Ein Expando
-Modell, das durch Abruf eines Werts aus dem Datenspeicher erstellt wird, hat Attribute für alle Attributwerte, die im Datenspeicher gespeichert sind.
Eine Anwendung kann einer abgeleiteten Expando
-Klasse vordefinierte Attribute hinzufügen:
...
Damit erhält employee
das Attribut name
mit dem Wert 'Sandy'
, ein age
-Attribut mit dem Wert None
und ein dynamisches Attribut location
mit dem Wert 'SF'
.
Zum Erstellen einer abgeleiteten Klasse Expando
, deren Attribute nicht indexiert sind, legen Sie in der Definition der abgeleiteten _default_indexed = False
-Klasse fest:
...
Sie können auch _default_indexed
für eine Expando
-Entität festlegen.
In diesem Fall wirkt sich dies auf alle Attribute aus, die nach dem Festlegen zugewiesen wurden.
Eine andere hilfreiche Technik ist das Abfragen einer Expando
-Art nach einem dynamischen Attribut. Eine Abfrage wie
kann nicht funktionieren, da die Klasse kein Attributobjekt für das Standortattribut hat. Verwenden Sie stattdessen GenericProperty
, d. h. die Klasse, die Expando
für dynamische Attribute nutzt:
Modell-Hooks verwenden
NDB bietet ein einfaches Hook-Verfahren. Durch Definition eines Hooks kann eine Anwendung Code vor oder nach bestimmten Vorgängen ausführen. Beispielsweise lässt sich mit Model
vor jeder get()
-Methode eine Funktion ausführen.
Eine Hook-Funktion wird ausgeführt, wenn synchrone, asynchrone und mehrere Versionen der entsprechenden Methode verwendet werden. Beispiel: Ein "Pre-Get"-Hook gilt für alle get()
-, get_async()
- und get_multi()
-Methoden. Für jeden Hook gibt es Pre-RPC- und Post-RPC-Versionen.
Hooks können für Folgendes nützlich sein:
- Abfrage-Caching
- Überwachen der Cloud Datastore-Aktivität pro Nutzer
- Datenbank-Trigger nachahmen
Das folgende Beispiel zeigt, wie Hook-Funktionen definiert werden:
...
...
Wenn Sie Post-Hooks mit asynchronen APIs verwenden, werden die Hooks durch Aufruf von check_result()
oder get_result()
oder durch die Ausgabe des Future-Arguments einer asynchronen Methode (in einem Tasklet) ausgelöst.
Post-Hooks prüfen nicht, ob der RPC erfolgreich war. Der Hook wird auch bei Fehlern ausgeführt.
Alle Post-Hooks haben das Argument Future am Ende der Aufrufsignatur. Dieses Future
-Objekt beinhaltet das Ergebnis der Aktion. Sie können für den Abruf des Ergebnisses die Methode get_result()
für dieses Future
-Objekt aufrufen. get_result()
blockiert dabei nicht, da das Future
-Objekt zum Zeitpunkt des Hook-Aufrufs vollständig ist.
Durch Auslösen einer Ausnahme während eines Pre-Hooks wird verhindert, dass die Anfrage ausgeführt wird.
Obwohl Hooks innerhalb von <var>*</var>_async
-Methoden ausgelöst werden, können Sie einen RPC nicht vorab ausführen, indem Sie tasklets.Return
in einem Pre-RPC-Hook auslösen.