Classe PolyModel

Remarque : Les développeurs qui créent des applications sont vivement encouragés à utiliser la bibliothèque cliente NDB, qui présente plusieurs avantages par rapport à cette bibliothèque cliente, tels que la mise en cache automatique des entités via l'API Memcache. Si vous utilisez actuellement l'ancienne bibliothèque cliente DB, consultez le guide de migration de DB vers NDB.

La classe PolyModel est la superclasse des définitions de modèles de données qui peuvent elles-mêmes représenter des super-classes d'autres définitions de modèles de données. Une requête générée à partir d'une classe PolyModel peut renvoyer des résultats correspondant à des instances de la classe ou de l'une de ses sous-classes.

La classe PolyModel est fournie par le module google.appengine.ext.db.polymodel.

PolyModel, qui est une sous-classe de Model, hérite de cette classe ses méthodes d'instance et de classe. La classe PolyModel remplace plusieurs méthodes de la classe Model, mais elle n'introduit aucun nouvel élément d'interface.

Présentation

Il s'avère souvent judicieux de définir les modèles de données comme une arborescence de classification, à la manière d'une base de données d'objets qui définit une classe d'objets en tant que sous-classe d'une autre. Ce type de base de données peut effectuer des requêtes sur des objets de la classe parent et inclure des objets de la sous-classe dans les résultats. Le datastore App Engine n'accepte pas ce genre de requêtes de manière native, mais vous pouvez le mettre en œuvre à l'aide d'un mécanisme inclus dans le SDK Python : la classe PolyModel.

Une classe de modèles dérivée de PolyModel peut constituer la classe de base d'autres classes de modèles. Les requêtes créées pour ces classes à l'aide des méthodes all() et gql() savent inclure des instances de sous-classes dans les résultats.

Les sous-classes peuvent définir de nouvelles propriétés qui n'existent pas dans les classes parentes. Toutefois, les sous-classes ne peuvent pas écraser des définitions de propriétés de classes parentes (cela entraîne une erreur DuplicateProperty).

À titre de référence, voici l'exemple simple tiré de la page Entités et modèles. Notez que la classe PolyModel est fournie par le package google.appengine.ext.db.polymodel.

from google.appengine.ext import db
from google.appengine.ext.db import polymodel

class Contact(polymodel.PolyModel):
    phone_number = db.PhoneNumberProperty()
    address = db.PostalAddressProperty()

class Person(Contact):
    first_name = db.StringProperty()
    last_name = db.StringProperty()
    mobile_number = db.PhoneNumberProperty()

class Company(Contact):
    name = db.StringProperty()
    fax_number = db.PhoneNumberProperty()

p = Person(phone_number='1-206-555-9234',
           address='123 First Ave., Seattle, WA, 98101',
           first_name='Alfred',
           last_name='Smith',
           mobile_number='1-206-555-0117')
p.put()

c = Company(phone_number='1-503-555-9123',
            address='P.O. Box 98765, Salem, OR, 97301',
            name='Data Solutions, LLC',
            fax_number='1-503-555-6622')
c.put()

for contact in Contact.all():
  # Returns both p and c.
  # ...

for person in Person.all():
  # Returns only p.
  # ...

Le polymorphisme n'est pas une fonctionnalité native du datastore. Au lieu de cela, il est mis en œuvre dans la classe PolyModel elle-même. Toutes les entités créées à partir de sous-classes PolyModel sont stockées dans le datastore avec le même genre, qui est le nom de la classe racine (par exemple, Animal). Chaque objet stocke sa hiérarchie de classes en tant que propriété à valeurs multiples de l'entité nommée 'class'. Lorsque l'application crée une requête à l'aide de la méthode all() ou gql() d'une classe PolyModel, cette requête inclut un filtre sur la propriété 'class' qui limite les résultats aux entités créées à partir de la classe ou de toute sous-classe.

Étant donné que PolyModel stocke les informations sur la classe à l'aide d'une propriété de l'entité, les index des requêtes polymorphes doivent s'adapter à la propriété 'class'. Le filtre implicite est un filtre d'égalité, et peut être associé à d'autres filtres d'égalité et d'inégalité sur d'autres propriétés.

Remarque : PolyModel n'utilise que les noms des classes de la propriété 'class', et non les chemins d'accès complets. Il est possible de créer des hiérarchies de classes comportant plusieurs nœuds du même nom, par exemple A → B et A → C → B. Une requête sur l'une renvoie des entités appartenant aux deux. De même, les requêtes pour A → B → C et A → C → B sont identiques d'un point de vue fonctionnel. Nous vous recommandons d'éviter de créer une seule hiérarchie de classes comportant plusieurs nœuds du même nom.

PolyModel n'est pas compatible avec le remplacement des définitions de modèles de propriété dans les sous-classes. Si une sous-classe tente de redéfinir une propriété définie sur une super-classe, la définition de la classe déclenche une erreur DuplicatePropertyError.

PolyModel accepte l'héritage multiple, y compris l'héritage de plusieurs classes partageant une super-classe (héritage "en diamant"). Une classe ne peut pas hériter de deux classes qui définissent chacune une définition de modèle de propriété pour la même propriété (cela déclencherait une erreur DuplicatePropertyError). Toutefois, une classe peut hériter de deux classes qui héritent de la même définition de modèle de propriété à partir de la même super-classe.

PolyModel n'est pas compatible avec les propriétés dynamiques, contrairement à Expando. Il n'existe pas d'équivalent de PolyModel pour Expando.

Constructeur

Le constructeur de la classe PolyModel est défini comme suit :

class PolyModel(parent=None, key_name=None, **kwds)

Classe de modèles qui peut servir de super-classe à d'autres classes de modèles et dont les requêtes peuvent renvoyer comme résultats des instances de sous-classes. Tout comme la classe Model, la classe PolyModel doit être sous-classée pour définir le genre des entités de données.

La classe PolyModel, qui est une sous-classe de Model, hérite de ses méthodes ou les remplace.

Arguments

parent
Instance Model ou Key de l'entité parente de la nouvelle entité.
key_name

Nom de la nouvelle entité. Le nom fait partie de la clé primaire. Si la valeur est None, un ID généré par le système est utilisé pour la clé.

La valeur de key_name ne doit pas commencer par un nombre et ne doit pas se présenter au format __*__. Si l'application utilise des données soumises par l'utilisateur en tant que noms de clés d'entité Datastore (telles qu'une adresse e-mail), elle doit d'abord nettoyer la valeur pour satisfaire ces exigences, par exemple en la préfixant à l'aide d'une chaîne connue telle que "key:".

Un argument key_name est stocké en tant que chaîne Unicode, avec les valeurs str converties en texte ASCII.

**kwds
Valeurs initiales des propriétés de l'instance, sous la forme d'arguments à mots clés. Chaque nom correspond à un attribut de la nouvelle instance et doit correspondre aux propriétés fixes définies dans la classe PolyModel.

Méthodes de la classe

En plus des méthodes de classe définies par la classe Model, la classe PolyModel fournit les méthodes suivantes :

PolyModel.class_key()

Renvoie le nom de la classe et les noms de toutes les classes parentes de la classe, sous la forme d'un tuple.

PolyModel.class_name()

Renvoie le nom de la classe. Une classe peut écraser cette méthode si le nom de la classe Python change, mais les entités doivent continuer d'utiliser le nom de la classe d'origine.

Cette page vous a-t-elle été utile ? Évaluez-la :

Envoyer des commentaires concernant…

Environnement standard App Engine pour Python 2