Merge pull request #806 from mmelliso/mmelliso/indexing
Generate Unique Indices for Lists of EmbeddedDocs
This commit is contained in:
commit
d27e1eee25
1
AUTHORS
1
AUTHORS
@ -215,3 +215,4 @@ that much better:
|
|||||||
* André Ericson https://github.com/aericson)
|
* André Ericson https://github.com/aericson)
|
||||||
* Mikhail Moshnogorsky (https://github.com/mikhailmoshnogorsky)
|
* Mikhail Moshnogorsky (https://github.com/mikhailmoshnogorsky)
|
||||||
* Diego Berrocal (https://github.com/cestdiego)
|
* Diego Berrocal (https://github.com/cestdiego)
|
||||||
|
* Matthew Ellison (https://github.com/mmelliso)
|
||||||
|
@ -5,6 +5,7 @@ Changelog
|
|||||||
|
|
||||||
Changes in 0.9.X - DEV
|
Changes in 0.9.X - DEV
|
||||||
======================
|
======================
|
||||||
|
- Generate Unique Indicies for Lists of EmbeddedDocuments #358
|
||||||
- Sparse fields #515
|
- Sparse fields #515
|
||||||
- write_concern not in params of Collection#remove #801
|
- write_concern not in params of Collection#remove #801
|
||||||
- Better BaseDocument equality check when not saved #798
|
- Better BaseDocument equality check when not saved #798
|
||||||
|
@ -816,6 +816,9 @@ class BaseDocument(object):
|
|||||||
index = {'fields': fields, 'unique': True, 'sparse': sparse}
|
index = {'fields': fields, 'unique': True, 'sparse': sparse}
|
||||||
unique_indexes.append(index)
|
unique_indexes.append(index)
|
||||||
|
|
||||||
|
if field.__class__.__name__ == "ListField":
|
||||||
|
field = field.field
|
||||||
|
|
||||||
# Grab any embedded document field unique indexes
|
# Grab any embedded document field unique indexes
|
||||||
if (field.__class__.__name__ == "EmbeddedDocumentField" and
|
if (field.__class__.__name__ == "EmbeddedDocumentField" and
|
||||||
field.document_type != cls):
|
field.document_type != cls):
|
||||||
|
@ -577,6 +577,38 @@ class IndexesTest(unittest.TestCase):
|
|||||||
|
|
||||||
BlogPost.drop_collection()
|
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):
|
def test_unique_with_embedded_document_and_embedded_unique(self):
|
||||||
"""Ensure that uniqueness constraints are applied to fields on
|
"""Ensure that uniqueness constraints are applied to fields on
|
||||||
embedded documents. And work with unique_with as well.
|
embedded documents. And work with unique_with as well.
|
||||||
|
@ -1974,14 +1974,14 @@ class FieldTest(unittest.TestCase):
|
|||||||
def test_recursive_embedding(self):
|
def test_recursive_embedding(self):
|
||||||
"""Ensure that EmbeddedDocumentFields can contain their own documents.
|
"""Ensure that EmbeddedDocumentFields can contain their own documents.
|
||||||
"""
|
"""
|
||||||
class Tree(Document):
|
|
||||||
name = StringField()
|
|
||||||
children = ListField(EmbeddedDocumentField('TreeNode'))
|
|
||||||
|
|
||||||
class TreeNode(EmbeddedDocument):
|
class TreeNode(EmbeddedDocument):
|
||||||
name = StringField()
|
name = StringField()
|
||||||
children = ListField(EmbeddedDocumentField('self'))
|
children = ListField(EmbeddedDocumentField('self'))
|
||||||
|
|
||||||
|
class Tree(Document):
|
||||||
|
name = StringField()
|
||||||
|
children = ListField(EmbeddedDocumentField('TreeNode'))
|
||||||
|
|
||||||
Tree.drop_collection()
|
Tree.drop_collection()
|
||||||
tree = Tree(name="Tree")
|
tree = Tree(name="Tree")
|
||||||
|
|
||||||
|
@ -512,16 +512,16 @@ class QuerySetTest(unittest.TestCase):
|
|||||||
|
|
||||||
def test_updates_can_have_match_operators(self):
|
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):
|
class Comment(EmbeddedDocument):
|
||||||
content = StringField()
|
content = StringField()
|
||||||
name = StringField(max_length=120)
|
name = StringField(max_length=120)
|
||||||
vote = IntField()
|
vote = IntField()
|
||||||
|
|
||||||
|
class Post(Document):
|
||||||
|
title = StringField(required=True)
|
||||||
|
tags = ListField(StringField())
|
||||||
|
comments = ListField(EmbeddedDocumentField("Comment"))
|
||||||
|
|
||||||
Post.drop_collection()
|
Post.drop_collection()
|
||||||
|
|
||||||
comm1 = Comment(content="very funny indeed", name="John S", vote=1)
|
comm1 = Comment(content="very funny indeed", name="John S", vote=1)
|
||||||
|
@ -318,6 +318,10 @@ class FieldTest(unittest.TestCase):
|
|||||||
def test_circular_reference(self):
|
def test_circular_reference(self):
|
||||||
"""Ensure you can handle circular references
|
"""Ensure you can handle circular references
|
||||||
"""
|
"""
|
||||||
|
class Relation(EmbeddedDocument):
|
||||||
|
name = StringField()
|
||||||
|
person = ReferenceField('Person')
|
||||||
|
|
||||||
class Person(Document):
|
class Person(Document):
|
||||||
name = StringField()
|
name = StringField()
|
||||||
relations = ListField(EmbeddedDocumentField('Relation'))
|
relations = ListField(EmbeddedDocumentField('Relation'))
|
||||||
@ -325,10 +329,6 @@ class FieldTest(unittest.TestCase):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Person: %s>" % self.name
|
return "<Person: %s>" % self.name
|
||||||
|
|
||||||
class Relation(EmbeddedDocument):
|
|
||||||
name = StringField()
|
|
||||||
person = ReferenceField('Person')
|
|
||||||
|
|
||||||
Person.drop_collection()
|
Person.drop_collection()
|
||||||
mother = Person(name="Mother")
|
mother = Person(name="Mother")
|
||||||
daughter = Person(name="Daughter")
|
daughter = Person(name="Daughter")
|
||||||
@ -1220,14 +1220,15 @@ class FieldTest(unittest.TestCase):
|
|||||||
self.assertEqual(page.tags[0], page.posts[0].tags[0])
|
self.assertEqual(page.tags[0], page.posts[0].tags[0])
|
||||||
|
|
||||||
def test_select_related_follows_embedded_referencefields(self):
|
def test_select_related_follows_embedded_referencefields(self):
|
||||||
class Playlist(Document):
|
|
||||||
items = ListField(EmbeddedDocumentField("PlaylistItem"))
|
class Song(Document):
|
||||||
|
title = StringField()
|
||||||
|
|
||||||
class PlaylistItem(EmbeddedDocument):
|
class PlaylistItem(EmbeddedDocument):
|
||||||
song = ReferenceField("Song")
|
song = ReferenceField("Song")
|
||||||
|
|
||||||
class Song(Document):
|
class Playlist(Document):
|
||||||
title = StringField()
|
items = ListField(EmbeddedDocumentField("PlaylistItem"))
|
||||||
|
|
||||||
Playlist.drop_collection()
|
Playlist.drop_collection()
|
||||||
Song.drop_collection()
|
Song.drop_collection()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user