Merge pull request #806 from mmelliso/mmelliso/indexing
Generate Unique Indices for Lists of EmbeddedDocs
This commit is contained in:
		
							
								
								
									
										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() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user