My favorites | Português | Sign in

A classe PolyModel

A classe PolyModel é a superclasse de definições de modelos de dados que podem por si só serem superclasses de outras definições de modelos de dados. Uma consulta produzida pela classe PolyModel pode ter como resultados instâncias da classe ou qualquer uma das suas subclasses.

PolyModel é fornecida pelo módulo google.appengine.ext.db.polymodel.

PolyModel é uma subclasse de Model e herda dela os métodos de classe e de instância. A classe PolyModel ignora vários métodos de Model, mas não apresenta elementos novos da interface.

Introdução

Muitas vezes é útil definir os modelos de dados como uma hierarquia de classificação, semelhante a como um banco de dados de objetos pode definir uma classe de objetos como uma subclasse de outra. Esse banco de dados pode realizar consultas em objetos da classe pai e incluir objetos da subclasse nos resultados. Originalmente, o armazenamento de dados do Google App Engine não oferece suporte a esse tipo de consulta, mas é possível implementá-lo usando um mecanismo incluído no SDK para Python, a classe PolyModel.

Uma classe de modelo derivada da PolyModel pode ser a classe base de outras classes de modelo. As consultas criadas para essas classes usando os métodos all() e gql() incluem instâncias de subclasses nos resultados.

As subclasses podem definir propriedades novas que não estão presentes nas classes pai. No entanto, elas não podem ignorar as definições das propriedades das classes pai (se isso acontecer, resultará em um erro DuplicateProperty).

Para referência, temos aqui um exemplo simples de Entidades e modelos. Observe que a classe PolyModel é fornecida pelo pacote 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 não oferece suporte a propriedades dinâmicas, como Expando faz. Não há um equivalente de PolyModel para Expando.

O polimorfismo não é um recurso original do armazenamento de dados. Em vez disso, o polimorfismo é implementado na própria classe PolyModel. Todas as entradas criadas a partir de subclasses PolyModel são armazenadas no armazenamento de dados com o mesmo tipo, que é o nome da classe raiz (por exemplo, Animal). Cada objeto armazena sua hierarquia de classes como uma propriedade de vários valores da entidade denominada 'class'. Quando o aplicativo cria uma consulta usando os métodos all() ou gql() da classe PolyModel, a consulta acrescenta um filtro na propriedade 'class' que limita os resultados para as entidades criadas a partir da classe ou de quaisquer subclasses.

Como PolyModel usa uma propriedade da entidade para armazenar informações sobre a classe, os índices de consultas polimórficas devem acomodar a propriedade 'class'. O filtro implícito é um filtro de igualdade e pode ser combinado com outros filtros de igualdade e desigualdade em outras propriedades.

Observação: PolyModel usa apenas os nomes das classes na propriedade 'class', e não os caminhos completos. É possível criar hierarquias de classes com vários nós do mesmo nome, como AB e ACB. Uma consulta feita a um deles retornará entidades dos dois. Da mesma maneira, consultas por ABC e ACB são funcionalmente idênticas. É melhor evitar criar uma hierarquia de classes única com vários nós do mesmo nome.

Construtor

O construtor da classe PolyModel é definido como é mostrado abaixo:

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

Uma classe de modelo que pode ser uma superclasse de outras classes de modelo e cujas consultas podem incluir instâncias de subclasses nos resultados. Assim como Model, a classe PolyModel deve ter subclasses para definir o tipo das entidades de dados.

PolyModel é uma subclasse de Model e herda ou ignora os seus métodos.

Argumentos:

parent
A instância de Model ou de Key para a entidade que é pai da nova entidade.
key_name

O nome da nova entidade. O nome se torna parte da chave principal. Se None, é usado um ID gerado pelo sistema para a chave.

O valor de key_name não deve começar com um número e não deve ter o formato __*__. Se seu aplicativo utiliza dados enviados pelo usuário como nomes de chave de entidade do armazenamento de dados (como um endereço de e-mail), o aplicativo deve limpar o valor primeiro, por exemplo, colocando como prefixo uma string conhecida como "key:", para atender a estes requisitos.

Um key_name é armazenado como string Unicode, com os valores de str convertidos em texto ASCII.

**kw
Valores iniciais das propriedades da instância, como argumentos de palavra-chave. Cada nome corresponde a um atributo da nova instância e deve corresponder às propriedades fixas definidas na classe PolyModel.

Métodos da classe

Além dos métodos da classe definidos pela classe Model, a classe PolyModel oferece os seguintes métodos de classes:

PolyModel.class_key()

Retorna o nome da classe e o nome de todas as classes pai da classe, como uma tupla.

PolyModel.class_name()

Retorna o nome da classe. Uma classe pode ignorar esse método se o nome da classe Python for alterado, mas as entidades devem continuar usando o nome original da classe.