Merge pull request #806 from mmelliso/mmelliso/indexing

Generate Unique Indices for Lists of EmbeddedDocs
This commit is contained in:
Yohan Graterol 2014-11-25 02:37:53 -05:00
commit d27e1eee25
7 changed files with 55 additions and 17 deletions

View File

@ -215,3 +215,4 @@ that much better:
* André Ericson https://github.com/aericson)
* Mikhail Moshnogorsky (https://github.com/mikhailmoshnogorsky)
* Diego Berrocal (https://github.com/cestdiego)
* Matthew Ellison (https://github.com/mmelliso)

View File

@ -5,6 +5,7 @@ Changelog
Changes in 0.9.X - DEV
======================
- Generate Unique Indicies for Lists of EmbeddedDocuments #358
- Sparse fields #515
- write_concern not in params of Collection#remove #801
- Better BaseDocument equality check when not saved #798

View File

@ -816,6 +816,9 @@ class BaseDocument(object):
index = {'fields': fields, 'unique': True, 'sparse': sparse}
unique_indexes.append(index)
if field.__class__.__name__ == "ListField":
field = field.field
# Grab any embedded document field unique indexes
if (field.__class__.__name__ == "EmbeddedDocumentField" and
field.document_type != cls):

View File

@ -577,6 +577,38 @@ class IndexesTest(unittest.TestCase):
BlogPost.drop_collection()
def test_unique_embedded_document_in_list(self):
"""
Ensure that the uniqueness constraints are applied to fields in
embedded documents, even when the embedded documents in in a
list field.
"""
class SubDocument(EmbeddedDocument):
year = IntField(db_field='yr')
slug = StringField(unique=True)
class BlogPost(Document):
title = StringField()
subs = ListField(EmbeddedDocumentField(SubDocument))
BlogPost.drop_collection()
post1 = BlogPost(
title='test1', subs=[
SubDocument(year=2009, slug='conflict'),
SubDocument(year=2009, slug='conflict')
]
)
post1.save()
post2 = BlogPost(
title='test2', subs=[SubDocument(year=2014, slug='conflict')]
)
self.assertRaises(NotUniqueError, post2.save)
BlogPost.drop_collection()
def test_unique_with_embedded_document_and_embedded_unique(self):
"""Ensure that uniqueness constraints are applied to fields on
embedded documents. And work with unique_with as well.

View File

@ -1974,14 +1974,14 @@ class FieldTest(unittest.TestCase):
def test_recursive_embedding(self):
"""Ensure that EmbeddedDocumentFields can contain their own documents.
"""
class Tree(Document):
name = StringField()
children = ListField(EmbeddedDocumentField('TreeNode'))
class TreeNode(EmbeddedDocument):
name = StringField()
children = ListField(EmbeddedDocumentField('self'))
class Tree(Document):
name = StringField()
children = ListField(EmbeddedDocumentField('TreeNode'))
Tree.drop_collection()
tree = Tree(name="Tree")

View File

@ -512,16 +512,16 @@ class QuerySetTest(unittest.TestCase):
def test_updates_can_have_match_operators(self):
class Post(Document):
title = StringField(required=True)
tags = ListField(StringField())
comments = ListField(EmbeddedDocumentField("Comment"))
class Comment(EmbeddedDocument):
content = StringField()
name = StringField(max_length=120)
vote = IntField()
class Post(Document):
title = StringField(required=True)
tags = ListField(StringField())
comments = ListField(EmbeddedDocumentField("Comment"))
Post.drop_collection()
comm1 = Comment(content="very funny indeed", name="John S", vote=1)

View File

@ -318,6 +318,10 @@ class FieldTest(unittest.TestCase):
def test_circular_reference(self):
"""Ensure you can handle circular references
"""
class Relation(EmbeddedDocument):
name = StringField()
person = ReferenceField('Person')
class Person(Document):
name = StringField()
relations = ListField(EmbeddedDocumentField('Relation'))
@ -325,10 +329,6 @@ class FieldTest(unittest.TestCase):
def __repr__(self):
return "<Person: %s>" % self.name
class Relation(EmbeddedDocument):
name = StringField()
person = ReferenceField('Person')
Person.drop_collection()
mother = Person(name="Mother")
daughter = Person(name="Daughter")
@ -1220,14 +1220,15 @@ class FieldTest(unittest.TestCase):
self.assertEqual(page.tags[0], page.posts[0].tags[0])
def test_select_related_follows_embedded_referencefields(self):
class Playlist(Document):
items = ListField(EmbeddedDocumentField("PlaylistItem"))
class Song(Document):
title = StringField()
class PlaylistItem(EmbeddedDocument):
song = ReferenceField("Song")
class Song(Document):
title = StringField()
class Playlist(Document):
items = ListField(EmbeddedDocumentField("PlaylistItem"))
Playlist.drop_collection()
Song.drop_collection()