Vous devez créer une classe de modèle pour votre entité. Pour cela, vous avez le choix entre deux méthodes :
- Créer une classe de modèle qui définit les propriétés de l'entité.
- Créer une classe de modèle Expando qui ne définit pas les entités à l'avance.
Ce document explique comment créer chacun de ces types de classes de modèle.
Il explique également comment créer un hook de modèle, afin que votre application puisse exécuter du code avant ou après un certain type d'opérations, par exemple avant chaque opération get()
.
Créer une classe de modèle avec des propriétés
Avant de créer une entité, vous devez créer une classe de modèle qui définit une ou plusieurs propriétés d'entité. Exemple :
...
où chaque entité de compte va avoir des propriétés correspondant au nom d'utilisateur, à l'ID d'utilisateur et à l'adresse e-mail.
Pour obtenir une liste complète des types de propriétés, consultez la documentation de référence relative aux propriétés d'entité.
Créer une classe de modèle Expando
Vous n'avez pas l'obligation d'utiliser une classe de modèle qui définit les propriétés à l'avance.
Une sous-classe de modèle spéciale nommée Expando
modifie le comportement de ses entités, afin que tout attribut attribué soit enregistré dans le datastore. Notez que ces attributs ne peuvent pas commencer par un trait de soulignement.
Voici comment créer un modèle Expando :
...
Ce code écrit dans le datastore une entité avec une propriété foo
ayant la valeur entière 1
, une propriété bar
ayant la valeur de chaîne 'blah'
et une propriété tag
répétée avec les valeurs de chaîne 'exp'
, 'and'
et 'oh'
.
Les propriétés sont indexées, et vous pouvez les inspecter à l'aide de l'attribut _properties
de l'entité :
Une sous-classe Expando
créée en extrayant une valeur du datastore possède des propriétés pour toutes les valeurs de propriété enregistrées dans le datastore.
Une application peut ajouter des propriétés prédéfinies à une sous-classe Expando
:
...
Cela donne à employee
un attribut name
ayant la valeur 'Sandy'
, un attribut age
ayant la valeur None
et un attribut dynamique location
ayant la valeur 'SF'
.
Pour créer une sous-classe Expando
dont les propriétés ne sont pas indexées, spécifiez _default_indexed = False
dans la définition de la sous-classe :
...
Vous pouvez également définir _default_indexed
sur une entité Expando
.
Dans ce cas, toutes les propriétés attribuées après la configuration seront affectées.
Une autre technique utile consiste à interroger un genre Expando
pour une propriété dynamique. Une requête comme celle-ci :
ne fonctionnera pas, car la classe n'a pas d'objet de propriété pour la propriété d'emplacement. Optez plutôt pour GenericProperty
, la classe que Expando
utilise pour les propriétés dynamiques :
Utiliser des hooks de modèle
NDB offre un mécanisme de hooking léger. Lorsqu'un hook est défini, une application peut exécuter du code avant ou après un certain type d'opérations. Par exemple, un Model
peut exécuter une fonction avant chaque opération get()
.
Une fonction de hook s'exécute lors de l'utilisation des versions synchrones, asynchrones et multi de la méthode correspondante. Par exemple, un hook "pré-get" s'appliquerait à toutes les opérations get()
, get_async()
et get_multi()
. Il existe des versions pré-RPC et post-RPC de chaque hook.
Les hooks peuvent être utiles pour les opérations suivantes :
- Mise en cache de requêtes
- Audit de l'activité Cloud Datastore par utilisateur
- Imitation de déclencheurs de base de données
L'exemple suivant montre comment définir des fonctions de hook :
...
...
Si vous utilisez des post-hooks avec des API asynchrones, ceux-ci sont déclenchés en appelant check_result()
ou get_result()
, ou en appliquant "yield" (dans un tasklet) à l'objet "Future" d'une méthode asynchrone.
Les post-hooks ne vérifient pas si le RPC a abouti, ils s'exécutent même en cas d'échec.
Tous les post-hooks disposent d'un argument Future à la fin de la signature de l'appel. Cet objet Future
contient le résultat de l'action. Vous pouvez appeler get_result()
sur cet objet Future
pour récupérer le résultat. Vous êtes ainsi certain que get_result()
ne se bloquera pas, car l'objet Future
est terminé au moment où le hook est appelé.
La génération d'une exception lors d'un pré-hook empêche la requête d'avoir lieu.
Bien que les hooks soient déclenchés à l'intérieur des méthodes <var>*</var>_async
, vous ne pouvez pas préempter un RPC en générant tasklets.Return
dans un hook pré-RPC.
Étapes suivantes
- Obtenez davantage d'informations sur la classe de modèle NDB.
- Explorez la documentation de référence relative aux propriétés d'entité.