From e1960f24738768d9ba2f19a3060cb1afb9967c27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastien=20G=C3=A9rard?= Date: Sat, 21 Mar 2020 15:09:12 +0100 Subject: [PATCH] - Drop Queryset .modify `full_response` parameter (deprecated a while ago and not working since pymongo3) - Fix Cursor 'snapshot' feature (now using cursor modifiers as expected by pymongo3+) --- docs/changelog.rst | 4 +++- mongoengine/queryset/base.py | 40 +++++++++------------------------ tests/queryset/test_queryset.py | 20 +++++++++++++++-- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 9b864b02b..ea92fa602 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -10,11 +10,13 @@ Development - Fixed a bug causing inaccurate query results, while combining ``__raw__`` and regular filters for the same field #2264 - Add support for the `elemMatch` projection operator in .fields() (e.g BlogPost.objects.fields(elemMatch__comments="test")) #2267 - DictField validate failed without default connection (bug introduced in 0.19.0) #2239 +- Fix cursor snapshot feature (`Doc.objects().snapshot(True)`), which was deprecated but is now working - Remove methods deprecated years ago: - - name parameter in Field constructor e.g `StringField(name="...")`, was replaced by db_field + - `name` parameter in Field constructor e.g `StringField(name="...")`, was replaced by db_field - Queryset.slave_okay() was deprecated since pymongo3 - dropDups was dropped with MongoDB3 - ``Queryset._ensure_indexes`` and ``Queryset.ensure_indexes``, the right method to use is ``Document.ensure_indexes`` + - Remove `full_response` from ``Queryset.modify``, as it is not working with Pymongo 3+ Changes in 0.19.1 ================= diff --git a/mongoengine/queryset/base.py b/mongoengine/queryset/base.py index eed304136..382d1a937 100644 --- a/mongoengine/queryset/base.py +++ b/mongoengine/queryset/base.py @@ -600,9 +600,7 @@ def update_one(self, upsert=False, write_concern=None, full_result=False, **upda **update ) - def modify( - self, upsert=False, full_response=False, remove=False, new=False, **update - ): + def modify(self, upsert=False, remove=False, new=False, **update): """Update and return the updated document. Returns either the document before or after modification based on `new` @@ -616,8 +614,6 @@ def modify( information about the command's execution. :param upsert: insert if document doesn't exist (default ``False``) - :param full_response: return the entire response object from the - server (default ``False``, not available for PyMongo 3+) :param remove: remove rather than updating (default ``False``) :param new: return updated rather than original document (default ``False``) @@ -639,9 +635,6 @@ def modify( sort = queryset._ordering try: - if full_response: - msg = "With PyMongo 3+, it is not possible anymore to get the full response." - warnings.warn(msg, DeprecationWarning) if remove: result = queryset._collection.find_one_and_delete( query, sort=sort, **self._cursor_args @@ -664,14 +657,8 @@ def modify( except pymongo.errors.OperationFailure as err: raise OperationError(u"Update failed (%s)" % err) - if full_response: - if result["value"] is not None: - result["value"] = self._document._from_son( - result["value"], only_fields=self.only_fields - ) - else: - if result is not None: - result = self._document._from_son(result, only_fields=self.only_fields) + if result is not None: + result = self._document._from_son(result, only_fields=self.only_fields) return result @@ -1151,10 +1138,7 @@ def snapshot(self, enabled): :param enabled: whether or not snapshot mode is enabled ..versionchanged:: 0.5 - made chainable - .. deprecated:: Ignored with PyMongo 3+ """ - msg = "snapshot is deprecated as it has no impact when using PyMongo 3+." - warnings.warn(msg, DeprecationWarning) queryset = self.clone() queryset._snapshot = enabled return queryset @@ -1594,25 +1578,23 @@ def _collection(self): @property def _cursor_args(self): - fields_name = "projection" - # snapshot is not handled at all by PyMongo 3+ - # TODO: evaluate similar possibilities using modifiers - if self._snapshot: - msg = "The snapshot option is not anymore available with PyMongo 3+" - warnings.warn(msg, DeprecationWarning) + projection_field_name = "projection" cursor_args = {} if not self._timeout: cursor_args["no_cursor_timeout"] = True + if self._snapshot: + cursor_args["modifiers"] = {"$snapshot": True} + if self._loaded_fields: - cursor_args[fields_name] = self._loaded_fields.as_dict() + cursor_args[projection_field_name] = self._loaded_fields.as_dict() if self._search_text: - if fields_name not in cursor_args: - cursor_args[fields_name] = {} + if projection_field_name not in cursor_args: + cursor_args[projection_field_name] = {} - cursor_args[fields_name]["_text_score"] = {"$meta": "textScore"} + cursor_args[projection_field_name]["_text_score"] = {"$meta": "textScore"} return cursor_args diff --git a/tests/queryset/test_queryset.py b/tests/queryset/test_queryset.py index f6d1a916e..3b53bcdf8 100644 --- a/tests/queryset/test_queryset.py +++ b/tests/queryset/test_queryset.py @@ -5595,10 +5595,10 @@ def test_create_count(self): self.Person.objects.create(name="Baz") assert self.Person.objects.count(with_limit_and_skip=True) == 3 - newPerson = self.Person.objects.create(name="Foo_1") + self.Person.objects.create(name="Foo_1") assert self.Person.objects.count(with_limit_and_skip=True) == 4 - def test_no_cursor_timeout(self): + def test_cursor_args_no_cursor_timeout(self): qs = self.Person.objects() assert qs._cursor_args == {} # ensure no regression of #2148 @@ -5608,6 +5608,22 @@ def test_no_cursor_timeout(self): qs = self.Person.objects().timeout(False) assert qs._cursor_args == {"no_cursor_timeout": True} + def test_cursor_args_snapshot(self): + self.Person.drop_collection() + self.Person.objects.create(name="Foo") + self.Person.objects.create(name="Bar") + self.Person.objects.create(name="Baz") + + qs = self.Person.objects() + assert qs._cursor_args == {} + + qs = self.Person.objects().snapshot(False) + assert qs._cursor_args == {} + + qs = self.Person.objects().snapshot(True) + assert qs._cursor_args == {"modifiers": {"$snapshot": True}} + assert len(list(qs)) == 3 + if __name__ == "__main__": unittest.main()