Python 2.7 has reached end of support
and will bedeprecatedon January 31, 2026. After deprecation, you won't be able to deploy Python 2.7
applications, even if your organization previously used an organization policy to
re-enable deployments of legacy runtimes. Your existing Python
2.7 applications will continue to run and receive traffic after theirdeprecation date. We recommend that
youmigrate to the latest supported version of Python.
Stay organized with collectionsSave and categorize content based on your preferences.
ThePolyModelclass lets an application define models that
support polymorphic queries, in a more flexible way than the standardModelclass.
A query produced from aPolyModelderived class can have results that are instances
of the classorany of its subclasses.
It is defined ingoogle.appengine.ext.ndb.polymodel. The following example shows
the flexibility provided by the PolyModel class.
Contact.query()returnsPersonandCompanyinstances;
ifContactderived fromModelinstead of fromPolyModel, each class would have a differentkindandContact.query()would not return instances of
proper subclasses ofContact.
If you wish to retrieve onlyPersoninstances,
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 betweenPolyModeland 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.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-09-04 UTC."],[[["\u003cp\u003eThis page outlines the use of legacy bundled services and APIs, specifically within the first-generation runtimes of the App Engine standard environment.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003ePolyModel\u003c/code\u003e class enables applications to define models that support polymorphic queries, allowing a query from a \u003ccode\u003ePolyModel\u003c/code\u003e derived class to return instances of the class or any of its subclasses.\u003c/p\u003e\n"],["\u003cp\u003e\u003ccode\u003ePolyModel\u003c/code\u003e provides class methods like \u003ccode\u003e_get_kind()\u003c/code\u003e, \u003ccode\u003e_class_name()\u003c/code\u003e, and \u003ccode\u003e_class_key()\u003c/code\u003e to manage class hierarchy and naming within the datastore.\u003c/p\u003e\n"],["\u003cp\u003eWhen using \u003ccode\u003ePolyModel\u003c/code\u003e, class names returned by \u003ccode\u003e_class_name()\u003c/code\u003e must be unique among subclasses to properly distinguish them within the datastore's \u003ccode\u003eclass_\u003c/code\u003e property.\u003c/p\u003e\n"]]],[],null,["# PolyModel Class\n\n| 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 the [migration guide](/appengine/migration-center/standard/migrate-to-second-gen/python-differences) to learn about your migration options for legacy bundled services.\n\nThe `PolyModel` class lets an application define models that\nsupport polymorphic queries, in a more flexible way than the standard `Model` class.\nA query produced from a `PolyModel` derived class can have results that are instances\nof the class *or* any of its subclasses.\n\nIt is defined in `google.appengine.ext.ndb.polymodel`. The following example shows\nthe flexibility provided by the PolyModel class.\n\n\n```python\nfrom google.appengine.ext import ndb\nfrom google.appengine.ext.ndb import polymodel\n\nclass Contact(polymodel.PolyModel):\n phone_number = ndb.PhoneNumberProperty()\n address = ndb.PostalAddressProperty()\n\nclass Person(Contact):\n first_name = ndb.StringProperty()\n last_name = ndb.StringProperty()\n mobile_number = ndb.PhoneNumberProperty()\n\nclass Company(Contact):\n name = ndb.StringProperty()\n fax_number = ndb.PhoneNumberProperty()\n\np = Person(phone_number='1-206-555-9234',\n address='123 First Ave., Seattle, WA, 98101',\n first_name='Alfred',\n last_name='Smith',\n mobile_number='1-206-555-0117')\np.put()\n\nc = Company(phone_number='1-503-555-9123',\n address='P.O. Box 98765, Salem, OR, 97301',\n name='Data Solutions, LLC',\n fax_number='1-503-555-6622')\nc.put()\n\nfor contact in Contact.query():\n print 'Phone: %s\\nAddress: %s\\n\\n' % (contact.phone_number, contact.address)\n```\n\n`Contact.query()` returns `Person`\nand `Company` instances;\nif `Contact` derived from `Model` instead of from\n`PolyModel`, each class would have a different `kind`\nand `Contact.query()` would not return instances of\nproper subclasses of `Contact`.\n\nIf you wish to retrieve only `Person` instances,\nuse `Person.query()`. You could also use\n`Contact.query(Contact.class_ == 'Person')`.\n\nIn addition to the regular Model methods,\nPolyModel has some interesting class methods:\n\n- `_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).\n- `_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.\n- `_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 between `PolyModel` and the current class, including the latter, but excluding PolyModel itself. This is the same as the value of the `class_` property. Its datastore name is 'class'.\n\nSince the class name is used in the `class_` property\nand this property is used to distinguish between the subclasses,\nthe class names (as returned by `_class_name()`) should be unique\namong those subclasses."]]