La classe PolyModel

Nota: gli sviluppatori che creano nuove applicazioni sono vivamente invitati a utilizzare la libreria client NDB, che offre diversi vantaggi rispetto a questa libreria client, ad esempio la memorizzazione nella cache automatica delle entità tramite l'API Memcache. Se al momento utilizzi la libreria client DB precedente, leggi la guida alla migrazione da DB a NDB

La classe PolyModel è la superclasse per le definizioni del modello dei dati che può essere a sua volta superclasse per altre definizioni del modello dei dati. Una query prodotta da un modello PolyModel può avere risultati che sono istanze del modello o di uno dei suoi sottomodelli.

PolyModel è fornito dal modulo google.appengine.ext.db.polymodel.

PolyModel è una sottoclasse di Model e ne eredita i metodi di classe e istanza. La classe PolyModel sostituisce diversi metodi del modello, ma non introduce nuovi elementi dell'interfaccia.

Introduzione

Spesso è utile definire i modelli di dati come una gerarchia di classificazione, in modo simile a come un database di oggetti può definire una classe di oggetti come sottoclasse di un'altra. Un database di questo tipo può eseguire query sugli oggetti della classe principale e includere gli oggetti della sottoclasse nei risultati. Il datastore di App Engine non supporta questo tipo di query in modo nativo, ma puoi implementarlo utilizzando un meccanismo incluso nell'SDK Python, la classe PolyModel.

Una classe del modello derivata da PolyModel può essere la classe base per altre classi di modello. Le query create per queste classi utilizzando i metodi all() e gql() sanno includere istanze di sottoclassi nei risultati.

Le sottoclassi possono definire nuove proprietà non presenti nelle classi principali. Tuttavia, le sottoclassi non possono sostituire le definizioni delle proprietà delle classi principali. In questo modo si verifica un errore DuplicateProperty.

Come riferimento, ecco un semplice esempio della sezione Entità e modelli. Tieni presente che la classe PolyModel è fornita dal pacchetto 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.
  # ...

Il polimorfismo non è una funzionalità nativa del datastore. Il polimorfismo viene implementato invece nella classe PolyModel stessa. Tutte le entità create dalle sottoclassi PolyModel vengono archiviate nel datastore con lo stesso tipo, ovvero il nome della classe principale (ad es. Animal). Ogni oggetto memorizza la propria gerarchia di classi come proprietà multivalore dell'entità denominata 'class'. Quando l'app crea una query utilizzando il metodo all() o gql() di una classe PolyModel, la query include un filtro sulla proprietà 'class' che limita i risultati alle entità create dalla classe o da qualsiasi sottoclasse.

Poiché PolyModel utilizza una proprietà dell'entità per memorizzare le informazioni sulla classe, gli indici per le query polimorfiche devono essere compatibili con la proprietà 'class'. Il filtro implicito è un filtro di uguaglianza e può essere combinato con altri filtri di uguaglianza e di disuguaglianza su altre proprietà.

Nota: PolyModel utilizza solo i nomi delle classi nella proprietà 'class', non i percorsi completi. È possibile creare gerarchie di classi con più nodi dello stesso nome, ad esempio AB e ACB. Una query per uno restituirà le entità di entrambi. Analogamente, le query per ABC e ACB sono funzionalmente identiche. È meglio evitare di creare una singola gerarchia di classi con più nodi con lo stesso nome.

PolyModel non supporta l'override delle definizioni del modello di proprietà nei sottoclassi. Se una sottoclasse tenta di ridefinire una proprietà definita in una superclasse, la definizione della classe genera un DuplicatePropertyError.

PolyModel supporta l'ereditarietà multipla, inclusa l'ereditarietà da più classi che condividono una superclasse ("ereditarietà a forma di diamante"). Una classe non può ereditare da due classi che definiscono ciascuna una definizione del modello di proprietà per la stessa proprietà (verrebbe generato un errore DuplicatePropertyError). Tuttavia, una classe può ereditare da due classi che ereditano la stessa definizione del modello di proprietà dalla stessa superclasse.

PolyModel non supporta le proprietà dinamiche, come fa Expando. Non esiste un equivalente di PolyModel per Expando.

Costruttore

Il costruttore della classe PolyModel è definito come segue:

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

Una classe di modello che può essere una superclasse di altre classi di modello e le cui query possono includere istanze di sottoclassi come risultati. Come Model, la classe PolyModel deve essere sottoclassificata per definire il tipo di entità di dati.

PolyModel è una sottoclasse di Model ed eredita o esegue l'override dei propri metodi.

Argomenti

parent
L'istanza Model o Key per l'entità principale della nuova entità.
key_name

Il nome della nuova entità. Il nome diventa parte della chiave primaria. Se None, per la chiave viene utilizzato un ID generato dal sistema.

Il valore di key_name non deve iniziare con un numero e non deve essere nel formato __*__. Se l'applicazione utilizza i dati inviati dagli utenti come nomi delle chiavi delle entità del datastore (ad esempio un indirizzo email), deve prima eseguire la saturazione del valore, ad esempio anteponendo una stringa nota come "chiave:", per soddisfare questi requisiti.

Un key_name viene archiviato come stringa Unicode, con i valori str convertiti in testo ASCII.

**kwds
Valori iniziali per le proprietà dell'istanza, come argomenti delle parole chiave. Ogni nome corrisponde a un attributo della nuova istanza e deve corrispondere alle proprietà fisse definite nella classe PolyModel.

Metodi di classe

Oltre ai metodi della classe definiti dalla classe Model, la classe PolyModel fornisce i seguenti metodi delle classi:

PolyModel.class_key()

Restituisce il nome della classe e i nomi di tutte le classi padre per la classe, sotto forma di tupla.

PolyModel.class_name()

Restituisce il nome del corso. Una classe può sostituire questo metodo se il nome della classe Python cambia, ma le entità devono continuare a utilizzare il nome della classe originale.