Nota:gli sviluppatori che creano nuove applicazioni sono fortemente incoraggiati a utilizzare la libreria client NDB, che offre diversi vantaggi rispetto a questa libreria client, ad esempio la memorizzazione automatica nella cache 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 dei modello dei dati che possono a loro volta essere superclassi per altre definizioni dei modello dei dati. Una query prodotta da una classe PolyModel può avere risultati che sono istanze della classe o di una delle sue sottoclassi.
PolyModel è fornito dal modulo google.appengine.ext.db.polymodel.
PolyModel è una sottoclasse di Model ed eredita i relativi metodi di classe e di istanza. La classe PolyModel esegue l'override di diversi metodi di Model, 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 sottoclasse di un'altra. Un database di questo tipo può eseguire query sugli oggetti della classe padre e includere gli oggetti della sottoclasse nei risultati. Il datastore 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 modello. Le query create per queste classi utilizzando i metodi all() e gql() includono le istanze delle sottoclassi nei risultati.
Le sottoclassi possono definire nuove proprietà non presenti nelle classi padre. Tuttavia, le sottoclassi non possono sostituire le definizioni delle proprietà delle classi principali. In caso contrario, si verifica un errore DuplicateProperty.
Per riferimento, ecco il semplice esempio di 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 funzionalità nativa del datastore. Il polimorfismo viene invece implementato nella classe PolyModel stessa. Tutte le entità create dalle sottoclassi di PolyModel vengono archiviate nel datastore con lo stesso tipo, ovvero il nome della classe radice (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 contenere la proprietà 'class'. Il filtro implicito è un filtro di uguaglianza e può essere combinato con altri filtri di uguaglianza e disuguaglianza su altre proprietà.
Nota:PolyModel utilizza solo i nomi delle classi nella proprietà 'class', non i percorsi completi. È possibile creare gerarchie di corsi con più nodi con lo stesso nome, ad esempio A → B e A → C → B. Una query per uno restituirà entità di entrambi. Allo stesso modo, le query per A → B → C e A → C → B 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à nelle 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 diamante"). Una classe non può ereditare da due classi che definiscono ciascuna una definizione di modello di proprietà per la stessa proprietà (in questo caso viene generato un DuplicatePropertyError). Tuttavia, una classe può ereditare da due classi che ereditano la stessa definizione di modello di proprietà dalla stessa superclasse.
PolyModel non supporta le proprietà dinamiche, come 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 sottoclassata per definire il tipo di entità di dati.
PolyModel è una sottoclasse di Model e ne eredita o esegue l'override dei metodi.
Argomenti
- genitore
- L'istanza del modello o l'istanza della chiave per l'entità che è l'entità principale 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 avere il formato
__*__. Se la tua applicazione utilizza i dati inviati dagli utenti come nomi delle chiavi delle entità del datastore (ad esempio un indirizzo email), l'applicazione deve prima sanificare il valore, ad esempio anteponendo una stringa nota come "key:", per soddisfare questi requisiti.Un
key_nameviene memorizzato come stringa Unicode, con i valoristrconvertiti come testo ASCII. - **kwds
- Valori iniziali per le proprietà dell'istanza, come argomenti di parole chiave. Ogni nome corrisponde a un attributo della nuova istanza e deve corrispondere alle proprietà fisse definite nella classe PolyModel.
Metodi della classe
Oltre ai metodi della classe definiti dalla classe Model, la classe PolyModel fornisce i seguenti metodi della classe:
- PolyModel.class_key()
-
Restituisce il nome della classe e i nomi di tutte le classi padre della classe, come tupla.
- PolyModel.class_name()
-
Restituisce il nome della classe. Una classe può eseguire l'override di questo metodo se il nome della classe Python cambia, ma le entità devono continuare a utilizzare il nome della classe originale.