Merge pull request #1005 from touilleMan/master
Raise error if save_condition fails #991
This commit is contained in:
commit
8909d1d144
1
AUTHORS
1
AUTHORS
@ -223,3 +223,4 @@ that much better:
|
|||||||
* Kiryl Yermakou (https://github.com/rma4ok)
|
* Kiryl Yermakou (https://github.com/rma4ok)
|
||||||
* Matthieu Rigal (https://github.com/MRigal)
|
* Matthieu Rigal (https://github.com/MRigal)
|
||||||
* Charanpal Dhanjal (https://github.com/charanpald)
|
* Charanpal Dhanjal (https://github.com/charanpald)
|
||||||
|
* Emmanuel Leblond (https://github.com/touilleMan)
|
||||||
|
@ -20,6 +20,7 @@ Changes in 0.9.X - DEV
|
|||||||
- Support for PyMongo 3+ #946
|
- Support for PyMongo 3+ #946
|
||||||
- Fix for issue where FileField deletion did not free space in GridFS.
|
- Fix for issue where FileField deletion did not free space in GridFS.
|
||||||
- No_dereference() not respected on embedded docs containing reference. #517
|
- No_dereference() not respected on embedded docs containing reference. #517
|
||||||
|
- Document save raise an exception if save_condition fails #1005
|
||||||
|
|
||||||
Changes in 0.9.0
|
Changes in 0.9.0
|
||||||
================
|
================
|
||||||
|
@ -266,7 +266,8 @@ class Document(BaseDocument):
|
|||||||
to cascading saves. Implies ``cascade=True``.
|
to cascading saves. Implies ``cascade=True``.
|
||||||
:param _refs: A list of processed references used in cascading saves
|
:param _refs: A list of processed references used in cascading saves
|
||||||
:param save_condition: only perform save if matching record in db
|
:param save_condition: only perform save if matching record in db
|
||||||
satisfies condition(s) (e.g., version number)
|
satisfies condition(s) (e.g. version number).
|
||||||
|
Raises :class:`OperationError` if the conditions are not satisfied
|
||||||
|
|
||||||
.. versionchanged:: 0.5
|
.. versionchanged:: 0.5
|
||||||
In existing documents it only saves changed fields using
|
In existing documents it only saves changed fields using
|
||||||
@ -284,6 +285,8 @@ class Document(BaseDocument):
|
|||||||
.. versionchanged:: 0.8.5
|
.. versionchanged:: 0.8.5
|
||||||
Optional save_condition that only overwrites existing documents
|
Optional save_condition that only overwrites existing documents
|
||||||
if the condition is satisfied in the current db record.
|
if the condition is satisfied in the current db record.
|
||||||
|
.. versionchanged:: 0.10
|
||||||
|
:class:`OperationError` exception raised if save_condition fails.
|
||||||
"""
|
"""
|
||||||
signals.pre_save.send(self.__class__, document=self)
|
signals.pre_save.send(self.__class__, document=self)
|
||||||
|
|
||||||
@ -348,6 +351,9 @@ class Document(BaseDocument):
|
|||||||
upsert = save_condition is None
|
upsert = save_condition is None
|
||||||
last_error = collection.update(select_dict, update_query,
|
last_error = collection.update(select_dict, update_query,
|
||||||
upsert=upsert, **write_concern)
|
upsert=upsert, **write_concern)
|
||||||
|
if not upsert and last_error['nModified'] == 0:
|
||||||
|
raise OperationError('Race condition preventing'
|
||||||
|
' document update detected')
|
||||||
created = is_new_object(last_error)
|
created = is_new_object(last_error)
|
||||||
|
|
||||||
if cascade is None:
|
if cascade is None:
|
||||||
|
@ -954,11 +954,12 @@ class InstanceTest(unittest.TestCase):
|
|||||||
self.assertEqual(w1.save_id, UUID(1))
|
self.assertEqual(w1.save_id, UUID(1))
|
||||||
self.assertEqual(w1.count, 0)
|
self.assertEqual(w1.count, 0)
|
||||||
|
|
||||||
# mismatch in save_condition prevents save
|
# mismatch in save_condition prevents save and raise exception
|
||||||
flip(w1)
|
flip(w1)
|
||||||
self.assertTrue(w1.toggle)
|
self.assertTrue(w1.toggle)
|
||||||
self.assertEqual(w1.count, 1)
|
self.assertEqual(w1.count, 1)
|
||||||
w1.save(save_condition={'save_id': UUID(42)})
|
self.assertRaises(OperationError,
|
||||||
|
w1.save, save_condition={'save_id': UUID(42)})
|
||||||
w1.reload()
|
w1.reload()
|
||||||
self.assertFalse(w1.toggle)
|
self.assertFalse(w1.toggle)
|
||||||
self.assertEqual(w1.count, 0)
|
self.assertEqual(w1.count, 0)
|
||||||
@ -986,7 +987,8 @@ class InstanceTest(unittest.TestCase):
|
|||||||
self.assertEqual(w1.count, 2)
|
self.assertEqual(w1.count, 2)
|
||||||
flip(w2)
|
flip(w2)
|
||||||
flip(w2)
|
flip(w2)
|
||||||
w2.save(save_condition={'save_id': old_id})
|
self.assertRaises(OperationError,
|
||||||
|
w2.save, save_condition={'save_id': old_id})
|
||||||
w2.reload()
|
w2.reload()
|
||||||
self.assertFalse(w2.toggle)
|
self.assertFalse(w2.toggle)
|
||||||
self.assertEqual(w2.count, 2)
|
self.assertEqual(w2.count, 2)
|
||||||
@ -998,7 +1000,8 @@ class InstanceTest(unittest.TestCase):
|
|||||||
self.assertTrue(w1.toggle)
|
self.assertTrue(w1.toggle)
|
||||||
self.assertEqual(w1.count, 3)
|
self.assertEqual(w1.count, 3)
|
||||||
flip(w1)
|
flip(w1)
|
||||||
w1.save(save_condition={'count__gte': w1.count})
|
self.assertRaises(OperationError,
|
||||||
|
w1.save, save_condition={'count__gte': w1.count})
|
||||||
w1.reload()
|
w1.reload()
|
||||||
self.assertTrue(w1.toggle)
|
self.assertTrue(w1.toggle)
|
||||||
self.assertEqual(w1.count, 3)
|
self.assertEqual(w1.count, 3)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user