Added support for compound primary keys (#149)

This commit is contained in:
Ross Lawley 2013-01-24 10:37:54 +00:00
parent d58f594c17
commit fff27f9b87
5 changed files with 52 additions and 12 deletions

View File

@ -135,4 +135,5 @@ that much better:
* Marcelo Anton * Marcelo Anton
* Aleksey Porfirov * Aleksey Porfirov
* Nicolas Trippar * Nicolas Trippar
* Manuel Hermann * Manuel Hermann
* Gustavo Gawryszewski

View File

@ -37,6 +37,7 @@ Changes in 0.8.X
- Added no_dereference context manager (#82) - Added no_dereference context manager (#82)
- Added switch_collection context manager (#220) - Added switch_collection context manager (#220)
- Added switch_collection method to document instances (#220) - Added switch_collection method to document instances (#220)
- Added support for compound primary keys (#149)
Changes in 0.7.9 Changes in 0.7.9
================ ================

View File

@ -2,7 +2,7 @@
Using MongoEngine with Django Using MongoEngine with Django
============================= =============================
.. note :: Updated to support Django 1.4 .. note:: Updated to support Django 1.4
Connecting Connecting
========== ==========
@ -10,7 +10,7 @@ In your **settings.py** file, ignore the standard database settings (unless you
also plan to use the ORM in your project), and instead call also plan to use the ORM in your project), and instead call
:func:`~mongoengine.connect` somewhere in the settings module. :func:`~mongoengine.connect` somewhere in the settings module.
.. note :: If getting an ``ImproperlyConfigured: settings.DATABASES is .. note:: If getting an ``ImproperlyConfigured: settings.DATABASES is
improperly configured`` error you may need to remove improperly configured`` error you may need to remove
``django.contrib.sites`` from ``INSTALLED_APPS`` in settings.py. ``django.contrib.sites`` from ``INSTALLED_APPS`` in settings.py.

View File

@ -135,7 +135,8 @@ arguments can be set on all fields:
field, will not have two documents in the collection with the same value. field, will not have two documents in the collection with the same value.
:attr:`primary_key` (Default: False) :attr:`primary_key` (Default: False)
When True, use this field as a primary key for the collection. When True, use this field as a primary key for the collection. `DictField`
and `EmbeddedDocuments` both support being the primary key for a document.
:attr:`choices` (Default: None) :attr:`choices` (Default: None)
An iterable (e.g. a list or tuple) of choices to which the value of this An iterable (e.g. a list or tuple) of choices to which the value of this
@ -441,6 +442,7 @@ The following example shows a :class:`Log` document that will be limited to
Indexes Indexes
======= =======
You can specify indexes on collections to make querying faster. This is done You can specify indexes on collections to make querying faster. This is done
by creating a list of index specifications called :attr:`indexes` in the by creating a list of index specifications called :attr:`indexes` in the
:attr:`~mongoengine.Document.meta` dictionary, where an index specification may :attr:`~mongoengine.Document.meta` dictionary, where an index specification may
@ -473,20 +475,22 @@ If a dictionary is passed then the following options are available:
:attr:`unique` (Default: False) :attr:`unique` (Default: False)
Whether the index should be unique. Whether the index should be unique.
.. note :: .. note::
To index embedded files / dictionary fields use 'dot' notation eg: Inheritance adds extra fields indices see: :ref:`document-inheritance`.
`rank.title`
.. warning:: Compound Indexes and Indexing sub documents
-------------------------------------------
Inheritance adds extra indices. Compound indexes can be created by adding the Embedded field or dictionary
If don't need inheritance for a document turn inheritance off - field name to the index definition.
see :ref:`document-inheritance`.
Sometimes its more efficient to index parts of Embeedded / dictionary fields,
in this case use 'dot' notation to identify the value to index eg: `rank.title`
Geospatial indexes Geospatial indexes
--------------------------- ------------------
Geospatial indexes will be automatically created for all Geospatial indexes will be automatically created for all
:class:`~mongoengine.GeoPointField`\ s :class:`~mongoengine.GeoPointField`\ s

View File

@ -693,5 +693,39 @@ class IndexesTest(unittest.TestCase):
index_item = [('_id', 1), ('comments.comment_id', 1)] index_item = [('_id', 1), ('comments.comment_id', 1)]
self.assertTrue(index_item in info) self.assertTrue(index_item in info)
def test_compound_key_embedded(self):
class CompoundKey(EmbeddedDocument):
name = StringField(required=True)
term = StringField(required=True)
class Report(Document):
key = EmbeddedDocumentField(CompoundKey, primary_key=True)
text = StringField()
Report.drop_collection()
my_key = CompoundKey(name="n", term="ok")
report = Report(text="OK", key=my_key).save()
self.assertEqual({'text': 'OK', '_id': {'term': 'ok', 'name': 'n'}},
report.to_mongo())
self.assertEqual(report, Report.objects.get(pk=my_key))
def test_compound_key_dictfield(self):
class Report(Document):
key = DictField(primary_key=True)
text = StringField()
Report.drop_collection()
my_key = {"name": "n", "term": "ok"}
report = Report(text="OK", key=my_key).save()
self.assertEqual({'text': 'OK', '_id': {'term': 'ok', 'name': 'n'}},
report.to_mongo())
self.assertEqual(report, Report.objects.get(pk=my_key))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()