Classe PolyModel

Nota: gli sviluppatori che creano nuove applicazioni sono vivamente incoraggiati a utilizzare la libreria client NDB, che offre diversi vantaggi rispetto a questa libreria client, come la memorizzazione nella cache automatica delle entità tramite l'API Memcache. Se attualmente utilizzi la libreria client DB precedente, leggi la Guida alla migrazione dal database a NDB

La classe PolyModel è la superclasse per le definizioni dei modello dei dati, che a loro volta possono essere superclassi per altre definizioni di modello dei dati. Una query prodotta da una classe PolyModel può avere risultati che sono istanze della classe o di una qualsiasi delle sue sottoclassi.

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

PolyModel è una sottoclasse di Model ed eredita i metodi della classe e dell'istanza da questa classe. La classe PolyModel sostituisce molti metodi del modello, ma non introduce nuovi elementi dell'interfaccia.

Introduzione

Spesso è utile definire i modelli di dati come una gerarchia di classificazione, proprio come un database di oggetti può definire una classe di oggetti come una sottoclasse di un'altra. Un database di questo tipo può eseguire query sugli oggetti della classe padre e includere 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 di modello derivata da PolyModel può essere la classe base per altre classi di modelli. Le query create per queste classi utilizzando i metodi all() e gql() sanno di includere nei risultati le istanze delle sottoclassi.

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 viene visualizzato un errore DuplicateProperty.

Come riferimento, ecco il semplice esempio tratto da Entità e modelli. Nota 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 caratteristica nativa del datastore. Il polimorfismo viene invece implementato nella classe PolyModel stessa. Tutte le entità create dalle sottoclassi PolyModel sono archiviate nel datastore con lo stesso tipo, ovvero il nome della classe principale (ad es. Animal). Ogni oggetto archivia la sua gerarchia di classi come proprietà a più valori 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 nella proprietà 'class' che limita i risultati alle entità create dalla classe o da qualsiasi sottoclasse.

Poiché PolyModel utilizza una proprietà dell'entità per archiviare le informazioni sulla classe, gli indici per le query polimorfiche devono contenere la proprietà 'class'. Il filtro implicito è un filtro di uguaglianza e può essere combinato con altri filtri di uguaglianza e con filtri 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 con lo stesso nome, ad esempio AB e ACB. Una query relativa a uno restituirà le entità di entrambi. Allo stesso modo, le query per ABC e ACB sono funzionalmente identiche. È meglio evitare di creare un'unica gerarchia di classi con più nodi con lo stesso nome.

PolyModel non supporta la sostituzione delle definizioni del modello di proprietà nelle sottoclassi. Se una sottoclasse cerca di ridefinire una proprietà definita in una superclasse, la definizione della classe genera un valore DuplicatePropertyError.

PolyModel supporta l'ereditarietà multipla, inclusa l'ereditarietà da più classi che condividono una superclasse (ereditarietà "diamante"). Una classe non può ereditare da due classi, ciascuna delle quali definisce la definizione del modello di proprietà per la stessa proprietà, il che genera un valore DuplicatePropertyError. Tuttavia, una classe può ereditare da due classi che ereditano la definizione del modello di proprietà dalla stessa superclasse.

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

Costruttore

Il costruttore della classe PolyModel è definito come segue:

class PolyModel(parent=Nessuno, parent=Nessuno, **parent)

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

PolyModel è una sottoclasse di Model e eredita o sostituisce i suoi metodi.

Argomenti

parent
L'istanza del modello o della chiave relativa all'entità padre della nuova entità.
key_name

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

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), l'applicazione deve prima eliminare il valore, ad esempio anteponendo a tale valore una stringa nota come "key:", per soddisfare questi requisiti.

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

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

Metodi delle classi

Oltre ai metodi delle classi 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.