Ensure that the update actions are grouped rather than serial.
This is a performance update. When multiple properties of the same entity have been deleted and modified, 2 calls to update the entity are made, one {"$set": … } and another {"$unset": … }. This is 2 network interface calls which is a performance killer (even at lan speeds). Fixes: #210
This commit is contained in:
parent
e537369d98
commit
7bb9c7d47f
@ -234,11 +234,16 @@ class Document(BaseDocument):
|
|||||||
select_dict[actual_key] = doc[actual_key]
|
select_dict[actual_key] = doc[actual_key]
|
||||||
|
|
||||||
upsert = self._created
|
upsert = self._created
|
||||||
|
work = {}
|
||||||
|
|
||||||
if updates:
|
if updates:
|
||||||
collection.update(select_dict, {"$set": updates},
|
work["$set"] = updates
|
||||||
upsert=upsert, safe=safe, **write_options)
|
|
||||||
if removals:
|
if removals:
|
||||||
collection.update(select_dict, {"$unset": removals},
|
work["$unset"] = removals
|
||||||
|
|
||||||
|
if work:
|
||||||
|
collection.update(select_dict, work,
|
||||||
upsert=upsert, safe=safe, **write_options)
|
upsert=upsert, safe=safe, **write_options)
|
||||||
|
|
||||||
warn_cascade = not cascade and 'cascade' not in self._meta
|
warn_cascade = not cascade and 'cascade' not in self._meta
|
||||||
|
@ -3515,6 +3515,36 @@ class ValidatorErrorTest(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertRaises(OperationError, change_shard_key)
|
self.assertRaises(OperationError, change_shard_key)
|
||||||
|
|
||||||
|
def test_set_unset_one_operation(self):
|
||||||
|
"""Ensure that $set and $unset actions are performed in the same
|
||||||
|
operation.
|
||||||
|
"""
|
||||||
|
class FooBar(Document):
|
||||||
|
meta = {
|
||||||
|
'collection': 'foobar',
|
||||||
|
}
|
||||||
|
|
||||||
|
foo = StringField(default=None)
|
||||||
|
bar = StringField(default=None)
|
||||||
|
|
||||||
|
FooBar.drop_collection()
|
||||||
|
|
||||||
|
# write an entity with a single prop
|
||||||
|
foo = FooBar(foo='foo')
|
||||||
|
foo.save()
|
||||||
|
|
||||||
|
self.assertEqual(foo.foo, 'foo')
|
||||||
|
|
||||||
|
# set foo to the default causing mongoengine to $unset foo.
|
||||||
|
foo.foo = None
|
||||||
|
foo.bar = 'bar'
|
||||||
|
|
||||||
|
foo.save()
|
||||||
|
foo.reload()
|
||||||
|
|
||||||
|
self.assertIsNone(foo.foo)
|
||||||
|
self.assertEqual(foo.bar, 'bar')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user