Cascading saves now default to off (#291)
This commit is contained in:
parent
c60ea40828
commit
fe62c3aacb
@ -4,6 +4,7 @@ Changelog
|
||||
|
||||
Changes in 0.8.X
|
||||
================
|
||||
- Cascading saves now default to off (#291)
|
||||
- ReferenceField now store ObjectId's by default rather than DBRef (#290)
|
||||
- Added ImageField support for inline replacements (#86)
|
||||
- Added SequenceField.set_next_value(value) helper (#159)
|
||||
|
@ -5,11 +5,21 @@ Upgrading
|
||||
0.7 to 0.8
|
||||
**********
|
||||
|
||||
Inheritance
|
||||
===========
|
||||
There have been numerous backwards breaking changes in 0.8. The reasons for
|
||||
these are ensure that MongoEngine has sane defaults going forward and
|
||||
performs the best it can out the box. Where possible there have been
|
||||
FutureWarnings to help get you ready for the change, but that hasn't been
|
||||
possible for the whole of the release.
|
||||
|
||||
.. warning:: Breaking changes - test upgrading on a test system before putting
|
||||
live. There maybe multiple manual steps in migrating and these are best honed
|
||||
on a staging / test system.
|
||||
|
||||
Data Model
|
||||
----------
|
||||
==========
|
||||
|
||||
Inheritance
|
||||
-----------
|
||||
|
||||
The inheritance model has changed, we no longer need to store an array of
|
||||
:attr:`types` with the model we can just use the classname in :attr:`_cls`.
|
||||
@ -105,6 +115,21 @@ eg::
|
||||
p._mark_as_dirty('friends')
|
||||
p.save()
|
||||
|
||||
|
||||
Cascading Saves
|
||||
---------------
|
||||
To improve performance document saves will no longer automatically cascade.
|
||||
Any changes to a Documents references will either have to be saved manually or
|
||||
you will have to explicitly tell it to cascade on save::
|
||||
|
||||
# At the class level:
|
||||
class Person(Document):
|
||||
meta = {'cascade': True}
|
||||
|
||||
# Or on save:
|
||||
my_document.save(cascade=True)
|
||||
|
||||
|
||||
Querysets
|
||||
=========
|
||||
|
||||
|
@ -244,7 +244,6 @@ class Document(BaseDocument):
|
||||
upsert=upsert, **write_concern)
|
||||
created = is_new_object(last_error)
|
||||
|
||||
warn_cascade = not cascade and 'cascade' not in self._meta
|
||||
cascade = (self._meta.get('cascade', True)
|
||||
if cascade is None else cascade)
|
||||
if cascade:
|
||||
@ -257,7 +256,7 @@ class Document(BaseDocument):
|
||||
if cascade_kwargs: # Allow granular control over cascades
|
||||
kwargs.update(cascade_kwargs)
|
||||
kwargs['_refs'] = _refs
|
||||
self.cascade_save(warn_cascade=warn_cascade, **kwargs)
|
||||
self.cascade_save(**kwargs)
|
||||
|
||||
except pymongo.errors.OperationFailure, err:
|
||||
message = 'Could not save document (%s)'
|
||||
@ -276,7 +275,7 @@ class Document(BaseDocument):
|
||||
signals.post_save.send(self.__class__, document=self, created=created)
|
||||
return self
|
||||
|
||||
def cascade_save(self, warn_cascade=None, *args, **kwargs):
|
||||
def cascade_save(self, *args, **kwargs):
|
||||
"""Recursively saves any references /
|
||||
generic references on an objects"""
|
||||
import fields
|
||||
@ -296,10 +295,6 @@ class Document(BaseDocument):
|
||||
|
||||
ref_id = "%s,%s" % (ref.__class__.__name__, str(ref._data))
|
||||
if ref and ref_id not in _refs:
|
||||
if warn_cascade:
|
||||
msg = ("Cascading saves will default to off in 0.8, "
|
||||
"please explicitly set `.save(cascade=True)`")
|
||||
warnings.warn(msg, FutureWarning)
|
||||
_refs.append(ref_id)
|
||||
kwargs["_refs"] = _refs
|
||||
ref.save(**kwargs)
|
||||
|
@ -17,7 +17,7 @@ __all__ = ('AllWarnings', )
|
||||
class AllWarnings(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
conn = connect(db='mongoenginetest')
|
||||
connect(db='mongoenginetest')
|
||||
self.warning_list = []
|
||||
self.showwarning_default = warnings.showwarning
|
||||
warnings.showwarning = self.append_to_warning_list
|
||||
@ -30,31 +30,6 @@ class AllWarnings(unittest.TestCase):
|
||||
# restore default handling of warnings
|
||||
warnings.showwarning = self.showwarning_default
|
||||
|
||||
def test_document_save_cascade_future_warning(self):
|
||||
|
||||
class Person(Document):
|
||||
name = StringField()
|
||||
parent = ReferenceField('self')
|
||||
|
||||
Person.drop_collection()
|
||||
|
||||
p1 = Person(name="Wilson Snr")
|
||||
p1.parent = None
|
||||
p1.save()
|
||||
|
||||
p2 = Person(name="Wilson Jr")
|
||||
p2.parent = p1
|
||||
p2.parent.name = "Poppa Wilson"
|
||||
p2.save()
|
||||
|
||||
self.assertTrue(len(self.warning_list) > 0)
|
||||
if len(self.warning_list) > 1:
|
||||
print self.warning_list
|
||||
warning = self.warning_list[0]
|
||||
self.assertEqual(FutureWarning, warning["category"])
|
||||
self.assertTrue("Cascading saves will default to off in 0.8"
|
||||
in str(warning["message"]))
|
||||
|
||||
def test_document_collection_syntax_warning(self):
|
||||
|
||||
class NonAbstractBase(Document):
|
||||
@ -67,6 +42,3 @@ class AllWarnings(unittest.TestCase):
|
||||
self.assertEqual(SyntaxWarning, warning["category"])
|
||||
self.assertEqual('non_abstract_base',
|
||||
InheritedDocumentFailTest._get_collection_name())
|
||||
|
||||
import sys
|
||||
sys.path[0:0] = [""]
|
||||
|
@ -678,7 +678,7 @@ class InstanceTest(unittest.TestCase):
|
||||
p1.reload()
|
||||
self.assertEqual(p1.name, p.parent.name)
|
||||
|
||||
def test_save_cascade_meta(self):
|
||||
def test_save_cascade_meta_false(self):
|
||||
|
||||
class Person(Document):
|
||||
name = StringField()
|
||||
@ -707,6 +707,31 @@ class InstanceTest(unittest.TestCase):
|
||||
p1.reload()
|
||||
self.assertEqual(p1.name, p.parent.name)
|
||||
|
||||
def test_save_cascade_meta_true(self):
|
||||
|
||||
class Person(Document):
|
||||
name = StringField()
|
||||
parent = ReferenceField('self')
|
||||
|
||||
meta = {'cascade': False}
|
||||
|
||||
Person.drop_collection()
|
||||
|
||||
p1 = Person(name="Wilson Snr")
|
||||
p1.parent = None
|
||||
p1.save()
|
||||
|
||||
p2 = Person(name="Wilson Jr")
|
||||
p2.parent = p1
|
||||
p2.save(cascade=True)
|
||||
|
||||
p = Person.objects(name="Wilson Jr").get()
|
||||
p.parent.name = "Daddy Wilson"
|
||||
p.save()
|
||||
|
||||
p1.reload()
|
||||
self.assertNotEqual(p1.name, p.parent.name)
|
||||
|
||||
def test_save_cascades_generically(self):
|
||||
|
||||
class Person(Document):
|
||||
|
Loading…
x
Reference in New Issue
Block a user