Mis favoritos | Español | Acceder

La clase PolyModel

La clase PolyModel es una superclase de definiciones de modelos de datos que a su vez pueden ser superclases de otras definiciones de modelos de datos. Una consulta producida a través de una clase PolyModel puede dar como resultado instancias de la propia clase o de cualquiera de sus subclases.

La clase PolyModel se proporciona a través del módulo google.appengine.ext.db.polymodel.

PolyModel es una subclase de Model y hereda su clase y los métodos de instancia de dicha clase. La clase PolyModel sobrescribe varios de los métodos de Model, aunque no introduce ningún elemento de interfaz nuevo.

Introducción

Con frecuencia, resulta útil definir los modelos de datos como una jerarquía clasificatoria, casi del mismo modo que una base de datos de objetos puede definir una clase de objetos como una subclase de otra. Dicha base de datos puede realizar consultas sobre objetos de la clase principal e incluir objetos de la subclase en los resultados. Este tipo de consultas no es compatible con Google App Engine de forma nativa. Sin embargo, puedes implementarlo mediante un mecanismo incluido en el SDK Python, la clase PolyModel.

Una clase de modelo derivada de PolyModel puede ser la clase base para otras clases de modelo. Las consultas creadas para estas clases mediante el uso de los métodos all() y gql() saben cómo incluir instancias de las subclases en los resultados.

Las subclases pueden definir las nuevas propiedades que no están presentes en las clases principales. Sin embargo, las subclases no pueden sobrescribir las definiciones de las propiedades de las clases principales. (Si se hace, se produce un error DuplicateProperty).

Si deseas obtener más información como referencia, consulta este sencillo ejemplo de Entidades y modelos. Ten en cuenta que la clase PolyModel está disponible en el paquete 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.
  # ...

PolyModel no es compatible con las propiedades dinámicas, en cambio Expando sí lo es. No existe un equivalente de la clase PolyModel para la clase Expando.

El polimorfismo no es una función nativa del almacén de datos. En su lugar, el polimorfismo se implementa en la clase PolyModel por sí mismo. Todas las entidades creadas a partir de la subclase PolyModel se almacenan en el almacén de datos con el mismo tipo: el nombre de la clase raíz (como, por ejemplo, Animal). Cada objeto almacena su jerarquía de clases como una propiedad con varios valores de la entidad denominada 'class'. Cuando la aplicación crea una consulta mediante los métodos all() o gql() de la clase PolyModel, la consulta incluye un filtro para la propiedad 'class' que limita los resultados de las entidades creadas a partir de esa clase o de cualquier subclase.

Debido a que la clase PolyModel utiliza una propiedad de la entidad para almacenar la información sobre la clase, los índices para las consultas polimórficas deben contener la propiedad 'class'. El filtro implícito es un filtro de igualdad que puede combinarse con otros filtros de igualdad o de desigualdad para otras propiedades.

Nota: la clase PolyModel utiliza únicamente los nombres de las clases de la propiedad 'class', no las rutas completas. Es posible crear las jerarquías de las clases mediante varios nodos del mismo nombre como, por ejemplo: A - B y A - C - B. Una consulta para una de ellas devolverá entidades de ambas. De forma similar, las consultas de A - B - C y A - C - B son idénticas funcionalmente. Es mejor evitar la creación de una sola jerarquía de clases con varios nodos del mismo nombre.

Constructor

El constructor de la clase PolyModel se define del siguiente modo:

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

Una clase de modelo que puede ser una superclase para otras clases de modelo y cuyas consultas pueden incluir instancias de subclases como resultado. Al igual que con la clase Model, se debe establecer una subclase de la clase PolyModel para definir el tipo de las entidades de datos.

PolyModel es una subclase de Model, por lo que hereda o sobrescribe sus métodos.

Argumentos:

parent
La instancia de Model o la instancia de Key para la entidad que representa la entidad principal de la nueva entidad.
key_name

El nombre de la nueva entidad. El nombre forma parte de la clave principal. Si es igual a None, se utilizará una ID generada por el sistema como clave.

El valor de key_name no debe comenzar por un número y no debe tener el formato __*__. Si tu aplicación utiliza datos enviados por el usuario como nombres de claves de entidades del almacén de datos (por ejemplo, una dirección de correo electrónico), la aplicación deberá depurar el valor en primer lugar. Una forma de hacerlo sería, por ejemplo, añadirle una cadena conocida como prefijo, como "key:", que cumpla estos requisitos.

key_name se almacena como una cadena de Unicode, con los valores str convertidos a texto ASCII.

**kw
Valores iniciales de las propiedades de la instancia, como argumentos de palabra clave. Cada nombre corresponde a un atributo de la instancia nueva y debe corresponder con las propiedades fijas definidas en la clase PolyModel.

Métodos de clase

Además de los métodos de clase definidos por la clase Model, la clase PolyModel proporciona los siguientes métodos de clase:

PolyModel.class_key()

Este método de clase devuelve el nombre de la clase y los nombres de todas las clases principales de la clase en forma de tupla.

PolyModel.class_name()

Este método de clase devuelve el nombre de la clase. Si se modifica el nombre de la clase Python, se puede sobrescribir este método mediante una clase, pero las entidades seguirían utilizando el nombre de la clase original.