Une classe qui hérite de la classe Model
représente la structure des entités stockées dans le datastore.
Les applications définissent des classes de modèle qui spécifient la structure de leurs entités, puis les instancient pour créer des entités.
Toutes les classes de modèle doivent hériter (directement ou indirectement) de Model.
Cette page contient une documentation de référence sur l'API. Si vous souhaitez obtenir une présentation, consultez Entités NDB et clés.
Présentation
Une classe qui hérite de la classe Model
décrit des entités Datastore.
Toutes les classes de modèle doivent hériter (directement ou indirectement) de Model
.
Vous pouvez déclarer la structure d'un modèle à l'aide d'affectations simples dans la définition de la classe de modèle :
from google.appengine.ext import ndb class Person(ndb.Model): name = ndb.StringProperty() age = ndb.IntegerProperty()
Vous pouvez maintenant créer une entité "Person" et l'écrire dans le datastore :
p = Person(name='Arthur Dent', age=42) k = p.put()
La valeur renvoyée par put()
est une clé, qui peut être utilisée pour récupérer la même entité ultérieurement comme suit :
p2 = k.get() p2 == p # Returns True
Pour mettre à jour une entité, il suffit de changer ses attributs et de la retransmettre (notez que cela ne modifie pas la clé) :
p2.name = 'Arthur Philip Dent' p2.put()
Si vous souhaitez supprimer une entité (à l'aide de la clé), vous pouvez utiliser la méthode suivante :
k.delete()
Les définitions de propriétés dans le corps de la classe indiquent au système les noms et les types des champs à stocker dans le datastore, s'ils doivent être indexés ou non, leur valeur par défaut, etc. Il existe un grand nombre de types de propriétés.
Le genre correspond généralement au nom de la classe (sans le modèle ou tout autre champ d'application parent). Pour remplacer le genre (ce qui peut être utile en cas de modification du schéma), définissez une méthode de classe nommée _get_kind()
, comme suit :
class MyModel(ndb.Model): @classmethod def _get_kind(cls): return 'AnotherKind'
Une application ne doit pas définir deux classes de modèle du même genre, même si elles se trouvent dans des modules différents. Les genres d'une application sont considérés comme un "espace de noms" global.
Les sous-classes Model
peuvent définir des hooks à exécuter avant ou après un appel pour la plupart des opérations (get, put, delete, allocate_ids).
Constructeur
Une application n'appelle normalement pas Model()
, mais elle est susceptible d'appeler le constructeur d'une classe qui hérite de Model
.
Cela crée une instance de ce modèle, aussi appelée entité.
L'entité nouvellement créée n'est pas automatiquement écrite dans le datastore.
Vous devez pour cela appeler explicitement put()
.
Arguments :
Les sous-classes Model
acceptent les arguments de mot clé suivants :
- key
- Instance Key de ce modèle. Si le paramètre
key
est utilisé, la valeur des argumentsid
etparent
doit être définie surNone
(valeur par défaut). - id
- ID de clé associé ce modèle. Si l'argument
id
est utilisé, la valeur du paramètre "key" doit être définie surNone
(valeur par défaut). - parent
- Instance Key du modèle parent ou
None
s'il s'agit d'un modèle de niveau supérieur. Siparent
est utilisé,key
doit êtreNone
. - namespace
- Espace de noms à utiliser pour cette entité, ou
None
(par défaut) pour utiliser l'espace de noms actuel. Sinamespace
est utilisé,key
doit êtreNone
.
Une application peut également utiliser des arguments de mot clé mappés aux propriétés du modèle. Par exemple, le code suivant fonctionne :
class Person(ndb.Model): name = StringProperty() age = IntegerProperty() p = Person(name='Arthur Dent', age=42)
Vous ne pouvez pas facilement définir une propriété nommée "key", "id", "parent" ou "namespace".
Si vous transmettez, par exemple, key="foo"
à un constructeur ou à un appel populate()
, la clé de l'entité est définie, et non un attribut de propriété nommé "key".
Remarque : Si vous remplacez le constructeur dans une sous-classe Model, sachez que celui-ci est également appelé de manière implicite dans certains cas. Assurez-vous donc de pouvoir traiter ces appels. Lorsqu'une entité est lue à partir du datastore, une entité vide est d'abord créée en appelant le constructeur sans arguments, après quoi les valeurs de clé et de propriétés sont définies une par une.
Lorsque get_or_insert()
ou get_or_insert_async()
crée une instance, il transmet **constructor_args au constructeur et définit ensuite la clé.
Méthodes des classes
- allocate_ids(size=None, max=None, parent=None, **ctx_options)
-
Alloue une plage d'ID de clé pour cette classe de modèle.
Arguments
- size
- Nombre d'ID à allouer. Vous pouvez spécifier l'argument
size
oumax
, mais pas les deux. - max
- Nombre maximal d'ID à allouer. Vous pouvez spécifier l'argument
size
oumax
, mais pas les deux. - parent
- Clé parente pour laquelle les ID seront alloués.
- **ctx_options
- Options de contexte
Renvoie un tuple au format (début, fin) pour la plage allouée. Les valeurs de début et de fin sont incluses.
Une application ne peut pas appeler
allocate_ids()
dans une transaction. - allocate_ids_async(size=None, max=None, parent=None, **ctx_options)
-
Version asynchrone de la méthode allocate_ids.
Renvoie un objet
Future
dont le résultat est un tuple au format (début, fin) pour la plage allouée. Les valeurs de début et de fin sont incluses. - get_by_id(id, parent=None, app=None, namespace=None, **ctx_options)
- Renvoie une entité par ID. Cette méthode est simplement un raccourci pour
Key(cls, id).get()
.Arguments
- id
- Chaîne ou ID de clé sous forme d'entier.
- parent
- Clé parente du modèle à récupérer.
- app (argument de mot clé)
- ID de l'application. S'il n'est pas spécifié, récupère les données de l'application actuelle.
- namespace (argument de mot clé)
- Espace de noms. S'il n'est pas spécifié, les données sont récupérées à partir de l'espace de noms par défaut.
- **ctx_options
- Options de contexte
Renvoie une instance de modèle ou
None
si aucune instance n'a été trouvée. - get_by_id_async(id, parent=None, app=None, namespace=None, **ctx_options)
- Version asynchrone de la méthode get_by_id.
Renvoie un objet
Future
dont le résultat est une instance de modèle ouNone
si aucun objet n'a été trouvé. - get_or_insert(key_name, parent=None, app=None, namespace=None, context_options=None, **constructor_args)
- Récupère de manière transactionnelle une entité existante ou en crée une nouvelle.
Arguments
- key_name
- Nom de clé (ID de clé de chaîne) à récupérer ou à créer.
- parent
- Clé de l'entité parente, le cas échéant.
- appli
- ID de l'application. S'il n'est pas spécifié, récupère les données de l'application actuelle.
- namespace
- Espace de noms. S'il n'est pas spécifié, les données sont récupérées à partir de l'espace de noms par défaut.
- context_options
- Options de contexte
Cette fonction permet également de transmettre des arguments de mot clé au constructeur de la classe de modèle si une instance associée au nom de clé spécifié n'existe pas déjà. S'il y a déjà une instance possédant le nom
key_name
et le parent fournis, ces arguments sont ignorés.Renvoie l'instance existante de la classe
Model
avec le nom de clé et le parent spécifiés, ou une instance nouvellement créée.Cette fonction utilise une transaction. Si le code qui l'appelle se trouve déjà dans une transaction, cette fonction tente de réutiliser la transaction existante. Si le groupe d'entités de cette fonction est incompatible avec la transaction existante, cela peut entraîner une erreur.
- get_or_insert_async(key_name, parent=None, app=None, namespace=None, context_options=None, **constructor_args)
-
Il s'agit de la version asynchrone de get_or_insert.
La méthode renvoie un objet
Future
dont le résultat est une instance existante de la classeModel
avec le nom de clé et le parent spécifiés, ou un objet nouvellement créé. - query([filter1, filter2, ...,] ancestor=None, app=None, namespace=None, filters=None, orders=None, default_options=None, projection=None distinct=False group_by=None)
-
Crée un objet
Query
pour cette classe, comme décrit dans la section Requêtes.L'argument de mot-clé
distinct
est un raccourci pour group_by = projection. Tous les autres arguments de mot clé sont transmis au constructeur de la requête.Si des arguments positionnels sont fournis, ils servent à configurer les filtres initiaux.
Renvoie un objet
Query
.
Méthodes des instances
- populate(**constructor_options)
-
Définit les valeurs des propriétés de l'entité. Ses arguments de mot clé reconnaissent les noms de propriétés automatiquement, de la même manière que le constructeur.
- put(**ctx_options)
-
Écrit les données de l'entité dans le datastore. Renvoie la clé de l'entité.
Arguments
- **ctx_options
- Options de contexte
- put_async(**ctx_options)
-
Écrit de manière asynchrone les données de l'entité dans le datastore. Renvoie un objet
Future
. Le résultat de l'objetFuture
est la clé de l'entité.Arguments
- **ctx_options
- Options de contexte
- to_dict(include=all, exclude=None)
-
Renvoie un
dict
contenant les valeurs de propriété du modèle. Les valeurs de propriété deStructuredProperty
etLocalStructuredProperty
sont converties de manière récursive en dictionnaires.Arguments :
- include
- Liste facultative de propriétés à inclure. Par défaut, toutes les propriétés sont incluses.
- exclude
- Liste facultative de propriétés à exclure. S'il y a un chevauchement entre les arguments include et exclude, l'argument exclude l'emporte.
Remarque : Si la valeur d'une propriété est un objet modifiable (par exemple une liste représentant une propriété répétée ou un dictionnaire ou une liste stockée dans un fichier
JsonProperty
), le même objet est renvoyé dans le dictionnaire stocké dans l'entité, sauf si la valeur est explicitement convertie (dans le cas d'uneStructuredProperty
, par exemple). La modification du dictionnaire entraîne alors la modification de l'entité, et inversement.
Données d'instance
- key
- Propriété spéciale permettant de stocker la clé Model.
Méthodes de hook
La sous-classe Model
d'une application peut définir une ou plusieurs de ces méthodes en tant que méthodes "hook" avant ou après l'opération.
Si vous souhaitez par exemple exécuter du code avant chaque opération "get", définissez la méthode _pre_get_hook()
de la sous-classe de modèle. Si vous avez besoin de conseils pour écrire des fonctions de hook, consultez Utiliser des hooks de modèle.
- @classmethod
_pre_allocate_ids_hook(cls, size, max, parent) - Hook qui s'exécute avant
allocate_ids()
- @classmethod
_post_allocate_ids_hook(cls, size, max, parent, future) - Hook qui s'exécute après
allocate_ids()
- @classmethod
_pre_delete_hook(cls, key) - Hook qui s'exécute avant
delete()
- @classmethod
_post_delete_hook(cls, key, future) - Hook qui s'exécute après
delete()
- @classmethod
_pre_get_hook(cls, key) - Hook qui s'exécute avant
Key.get()
lors de l'obtention d'une entité de ce modèle. - @classmethod
_post_get_hook(cls, key, future) - Hook qui s'exécute après
Key.get()
lors de l'obtention d'une entité de ce modèle. - _pre_put_hook(self)
- Hook qui s'exécute avant
put()
- _post_put_hook(self, future)
- Hook qui s'exécute après
put()
Introspection
Ces méthodes vous permettent d'inspecter les propriétés et la configuration d'un modèle donné. Elles s'avèrent utiles si vous écrivez une bibliothèque ou une fonction qui accepte plusieurs types de modèles.
Recherche par genre
Chaque modèle possède un genre qui est généralement identique au nom de la classe, sauf s'il a été remplacé. Vous pouvez utiliser le genre pour rechercher la classe de modèle associée à l'aide de _lookup_model
.
class Animal(ndb.Model): type = ndb.StringProperty() print Animal._get_kind() # 'Animal' print ndb.Model._lookup_model('Animal') # class Animal
Notez que _lookup_model
ne fonctionne que pour les classes de modèle qui ont déjà été importées par l'application.
Propriétés
Vous pouvez obtenir la liste de toutes les propriétés associées à un modèle à l'aide de l'option _properties
.
class User(ndb.Model): name = ndb.StringProperty() email = ndb.StringProperty() print User._properties # {'email': StringProperty('email'), 'name': StringProperty('name')}
_properties
fonctionne également pour les instances 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)}
Les instances de propriétés peuvent être inspectées. Les options fournies au constructeur sont disponibles en tant que propriétés précédées de _
.
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 de méthodes
Chaque méthode de la classe Model
possède un alias précédé de _
. Par exemple, _put()
correspond à put()
. Cela signifie que vous pouvez employer des noms de propriétés identiques aux noms de méthodes, à condition que vous utilisiez toujours les méthodes portant le préfixe "_
". Toutefois, notez que vous ne pouvez pas spécifier de propriétés nommées key
, parent
ou id
dans le constructeur.
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.
Si vous créez des bibliothèques tierces qui interagissent avec des modèles arbitraires, nous vous recommandons d'utiliser les méthodes avec le préfixe "_
".