Python 2.7 has reached end of supportand will bedeprecatedon January 31, 2026. After deprecation, you won't be able to deploy Python 2.7applications, even if your organization previously used an organization policy tore-enable deployments of legacy runtimes. Your existing Python2.7 applications will continue to run and receive traffic after theirdeprecation date. We recommend thatyoumigrate to the latest supported version of Python.

PolyModel Class

This page describes how to use the legacy bundled services and APIs. This API can only run in first-generation runtimes in the App Engine standard environment. If you are updating to the App Engine Python 3 runtime, refer to themigration guide to learn about your migration options for legacy bundled services.

ThePolyModel class lets an application define models that support polymorphic queries, in a more flexible way than the standardModel class. A query produced from aPolyModel derived class can have results that are instances of the classor any of its subclasses.

It is defined ingoogle.appengine.ext.ndb.polymodel. The following example shows the flexibility provided by the PolyModel class.

fromgoogle.appengine.extimportndbfromgoogle.appengine.ext.ndbimportpolymodelclassContact(polymodel.PolyModel):phone_number=ndb.PhoneNumberProperty()address=ndb.PostalAddressProperty()classPerson(Contact):first_name=ndb.StringProperty()last_name=ndb.StringProperty()mobile_number=ndb.PhoneNumberProperty()classCompany(Contact):name=ndb.StringProperty()fax_number=ndb.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()forcontactinContact.query():print'Phone:%s\nAddress:%s\n\n'%(contact.phone_number,contact.address)

Contact.query() returnsPerson andCompany instances; ifContact derived fromModel instead of fromPolyModel, each class would have a differentkind andContact.query() would not return instances of proper subclasses ofContact.

If you wish to retrieve onlyPerson instances, usePerson.query(). You could also useContact.query(Contact.class_ == 'Person').

In addition to the regular Model methods, PolyModel has some interesting class methods:

  • _get_kind(): the name of the root class; e.g.Person._get_kind() == 'Contact'. The root class, Contact in this example, may override this method to use a different name as the kind used in the datastore (for the entire hierarchy rooted here).
  • _class_name(): the name of the current class; e.g.Person._class_name() == 'Person'. A leaf class, Person in our example, may override this method to use a different name as the class name and in the class key. A non-leaf class may also override this method, but beware: its subclasses should also override it, or else they will all use the same class name, and you will soon be very confused.
  • _class_key(): a list of class names giving the hierarchy. For example,Person._class_key() == ['Contact', 'Person']. For deeper hierarchies, this will include all bases betweenPolyModel and the current class, including the latter, but excluding PolyModel itself. This is the same as the value of theclass_ property. Its datastore name is 'class'.

Since the class name is used in theclass_ property and this property is used to distinguish between the subclasses, the class names (as returned by_class_name()) should be unique among those subclasses.

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-12-15 UTC.