Inheritance is off by default (MongoEngine/mongoengine#122)

This commit is contained in:
Ross Lawley
2012-10-17 11:36:18 +00:00
parent 6f29d12386
commit 3d5b6ae332
20 changed files with 245 additions and 177 deletions

View File

@@ -4,6 +4,7 @@ Changelog
Changes in 0.8
==============
- Inheritance is off by default (MongoEngine/mongoengine#122)
- Remove _types and just use _cls for inheritance (MongoEngine/mongoengine#148)

View File

@@ -462,9 +462,10 @@ If a dictionary is passed then the following options are available:
The fields to index. Specified in the same format as described above.
:attr:`cls` (Default: True)
If you have polymorphic models that inherit and have `allow_inheritance`
turned on, you can configure whether the index should have the
:attr:`_cls` field added automatically to the start of the index.
If you have polymorphic models that inherit and have
:attr:`allow_inheritance` turned on, you can configure whether the index
should have the :attr:`_cls` field added automatically to the start of the
index.
:attr:`sparse` (Default: False)
Whether the index should be sparse.
@@ -573,7 +574,9 @@ defined, you may subclass it and add any extra fields or methods you may need.
As this is new class is not a direct subclass of
:class:`~mongoengine.Document`, it will not be stored in its own collection; it
will use the same collection as its superclass uses. This allows for more
convenient and efficient retrieval of related documents::
convenient and efficient retrieval of related documents - all you need do is
set :attr:`allow_inheritance` to True in the :attr:`meta` data for a
document.::
# Stored in a collection named 'page'
class Page(Document):
@@ -585,25 +588,20 @@ convenient and efficient retrieval of related documents::
class DatedPage(Page):
date = DateTimeField()
.. note:: From 0.7 onwards you must declare `allow_inheritance` in the document meta.
.. note:: From 0.8 onwards you must declare :attr:`allow_inheritance` defaults
to False, meaning you must set it to True to use inheritance.
Working with existing data
--------------------------
To enable correct retrieval of documents involved in this kind of heirarchy,
an extra attribute is stored on each document in the database: :attr:`_cls`.
These are hidden from the user through the MongoEngine interface, but may not
be present if you are trying to use MongoEngine with an existing database.
For this reason, you may disable this inheritance mechansim, removing the
dependency of :attr:`_cls`, enabling you to work with existing databases.
To disable inheritance on a document class, set :attr:`allow_inheritance` to
``False`` in the :attr:`meta` dictionary::
As MongoEngine no longer defaults to needing :attr:`_cls` you can quickly and
easily get working with existing data. Just define the document to match
the expected schema in your database. If you have wildly varying schemas then
a :class:`~mongoengine.DynamicDocument` might be more appropriate.
# Will work with data in an existing collection named 'cmsPage'
class Page(Document):
title = StringField(max_length=200, required=True)
meta = {
'collection': 'cmsPage',
'allow_inheritance': False,
'collection': 'cmsPage'
}

View File

@@ -84,12 +84,15 @@ using* the new fields we need to support video posts. This fits with the
Object-Oriented principle of *inheritance* nicely. We can think of
:class:`Post` as a base class, and :class:`TextPost`, :class:`ImagePost` and
:class:`LinkPost` as subclasses of :class:`Post`. In fact, MongoEngine supports
this kind of modelling out of the box::
this kind of modelling out of the box - all you need do is turn on inheritance
by setting :attr:`allow_inheritance` to True in the :attr:`meta`::
class Post(Document):
title = StringField(max_length=120, required=True)
author = ReferenceField(User)
meta = {'allow_inheritance': True}
class TextPost(Post):
content = StringField()

View File

@@ -8,10 +8,13 @@ Upgrading
Inheritance
-----------
Data Model
~~~~~~~~~~
The inheritance model has changed, we no longer need to store an array of
`types` with the model we can just use the classname in `_cls`. This means
that you will have to update your indexes for each of your inherited classes
like so:
:attr:`types` with the model we can just use the classname in :attr:`_cls`.
This means that you will have to update your indexes for each of your
inherited classes like so:
# 1. Declaration of the class
class Animal(Document):
@@ -40,6 +43,19 @@ like so:
Animal.objects._ensure_indexes()
Document Definition
~~~~~~~~~~~~~~~~~~~
The default for inheritance has changed - its now off by default and
:attr:`_cls` will not be stored automatically with the class. So if you extend
your :class:`~mongoengine.Document` or :class:`~mongoengine.EmbeddedDocuments`
you will need to declare :attr:`allow_inheritance` in the meta data like so:
class Animal(Document):
name = StringField()
meta = {'allow_inheritance': True}
0.6 to 0.7
==========
@@ -123,7 +139,7 @@ Document.objects.with_id - now raises an InvalidQueryError if used with a
filter.
FutureWarning - A future warning has been added to all inherited classes that
don't define `allow_inheritance` in their meta.
don't define :attr:`allow_inheritance` in their meta.
You may need to update pyMongo to 2.0 for use with Sharding.