Classe PolyModel

Observação: incentivamos fortementeos desenvolvedores que criam novos aplicativos a usar a Biblioteca de cliente NDB. Ela oferece diversos benefícios em comparação com esta biblioteca de cliente, como armazenamento em cache automático de entidades por meio da API Memcache. Se você estiver usando a antiga biblioteca de cliente de DB, leia o Guia de migração de DB para NDB.

A classe PolyModel é a superclasse de definições de modelo de dados que podem ser superclasses de outras definições desse tipo. Uma consulta produzida por uma classe PolyModel pode ter como resultados instâncias da classe ou qualquer uma das subclasses dela.

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

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

Introdução

Costuma ser útil definir modelos de dados como uma hierarquia de classificação, bem parecida com a maneira como um banco de dados de objetos pode definir uma classe de objetos como uma subclasse de outra. Esse banco de dados pode executar consultas em objetos da classe pai e incluir objetos da subclasse nos resultados. O armazenamento de dados do App Engine não aceita esse tipo de consulta de maneira nativa, mas você pode implementá-lo usando um mecanismo incluído no SDK do Python, a classe PolyModel.

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

As subclasses podem definir novas propriedades não presentes em classes pai. No entanto, as subclasses não podem modificar definições de propriedade das classes pai. Isso resulta em um erro DuplicateProperty.

Como referência, aqui está o exemplo simples de entidades e modelos. 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.
  # ...

O polimorfismo não é um recurso nativo do armazenamento de dados. Em vez disso, o polimorfismo é implementado na própria classe PolyModel. Todas as entidades criadas com base em subclasses PolyModel são guardadas no armazenamento de dados com o mesmo tipo, que é o nome da classe raiz (por exemplo, Animal). Cada objeto armazena a hierarquia de classe como uma propriedade com vários valores da entidade chamada 'class'. Quando o app cria uma consulta usando o método all() ou gql() da classe PolyModel, a consulta inclui um filtro na propriedade 'class'. Ele limita os resultados a entidades criadas com base na classe ou em qualquer subclasse.

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

Observação: a PolyModel usa apenas os nomes das classes na propriedade 'class', e não caminhos completos. É possível criar hierarquias de classe 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, as consultas de ABC e ACB são funcionalmente idênticas. É melhor evitar criar uma hierarquia de classe única com vários nós do mesmo nome.

PolyModel não aceita a substituição de definições de modelo de propriedade em subclasses. Caso uma subclasse tente redefinir uma propriedade definida em uma superclasse, a definição da classe gera um DuplicatePropertyError.

PolyModel aceita herança múltipla, inclusive herança de várias classes que compartilham uma superclasse (herança "diamante"). Uma classe não pode ser herdada de duas classes que definem uma definição de modelo de propriedade para a mesma propriedade (isso geraria um DuplicatePropertyError). Entretanto, uma classe pode herdar de duas classes que herdam a mesma definição de modelo de propriedade da mesma superclasse.

A PolyModel não aceita propriedades dinâmicas, como o Expando. Não há um equivalente de PolyModel para Expando.

Construtor

O construtor da classe PolyModel é definido assim:

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

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

A PolyModel é uma subclasse de Model e herda ou modifica os métodos dela.

Argumentos

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

O nome da nova entidade. Ele se torna parte da chave primária. Em caso de None, um ID gerado pelo sistema será usado para a chave.

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

Um key_name é armazenado como uma string Unicode, com valores str convertidos como texto ASCII.

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

Métodos de classe

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

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 poderá modificar esse método se o nome da classe Python for alterado, mas as entidades precisam continuar usando o nome da classe original.

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Ambiente padrão do App Engine para Python 2