From 28d7d6567633164a91459253df6a2981156703cd Mon Sep 17 00:00:00 2001 From: Ido Shraga Date: Wed, 6 Jul 2022 15:35:34 +0300 Subject: [PATCH] fix none has no effact in update/aggregate / first and cause query on all collection --- mongoengine/queryset/base.py | 12 ++++++++++++ tests/queryset/test_queryset.py | 13 +++++++++++++ tests/queryset/test_queryset_aggregation.py | 17 +++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/mongoengine/queryset/base.py b/mongoengine/queryset/base.py index 4ea6b10e1..30bf6a4a3 100644 --- a/mongoengine/queryset/base.py +++ b/mongoengine/queryset/base.py @@ -289,6 +289,9 @@ def create(self, **kwargs): def first(self): """Retrieve the first object matching the query.""" queryset = self.clone() + if self._none or self._empty: + return None + try: result = queryset[0] except IndexError: @@ -551,6 +554,8 @@ def update( if write_concern is None: write_concern = {} + if self._none or self._empty: + return 0 queryset = self.clone() query = queryset._query @@ -673,6 +678,9 @@ def modify( if not update and not upsert and not remove: raise OperationError("No update parameters, must either update or remove") + if self._none or self._empty: + return None + queryset = self.clone() query = queryset._query if not remove: @@ -1305,6 +1313,10 @@ def aggregate(self, pipeline, *suppl_pipeline, **kwargs): user_pipeline += suppl_pipeline initial_pipeline = [] + if self._none or self._empty: + initial_pipeline.append({"$limit": 1}) + initial_pipeline.append({"$match": {"fldksjhkjhafds": "lasdjfhlasdhfk"}}) + if self._query: initial_pipeline.append({"$match": self._query}) diff --git a/tests/queryset/test_queryset.py b/tests/queryset/test_queryset.py index 2fd170bb0..a659ca1dd 100644 --- a/tests/queryset/test_queryset.py +++ b/tests/queryset/test_queryset.py @@ -408,6 +408,19 @@ class A(Document): A.drop_collection() A().save() + # validate collection not empty + assert A.objects.count() == 1 + + # update operations + assert A.objects.none().update(s="1") == 0 + assert A.objects.none().update_one(s="1") == 0 + assert A.objects.none().modify(s="1") is None + + # validate noting change by update operations + assert A.objects(s="1").count() == 0 + + # fetch queries + assert A.objects.none().first() is None assert list(A.objects.none()) == [] assert list(A.objects.none().all()) == [] assert list(A.objects.none().limit(1)) == [] diff --git a/tests/queryset/test_queryset_aggregation.py b/tests/queryset/test_queryset_aggregation.py index ecc0db6e0..f1d504c0b 100644 --- a/tests/queryset/test_queryset_aggregation.py +++ b/tests/queryset/test_queryset_aggregation.py @@ -276,6 +276,23 @@ class Aggr(Document): {"_id": agg2.id, "c": 0.0, "name": "Y"}, ] + def test_queryset_aggregation_none(self): + class Person(Document): + name = StringField() + age = IntField() + + Person.drop_collection() + + p1 = Person(name="Isabella Luanna", age=16) + p2 = Person(name="Wilson Junior", age=21) + p3 = Person(name="Sandra Mara", age=37) + Person.objects.insert([p1, p2, p3]) + + pipeline = [{"$project": {"name": {"$toUpper": "$name"}}}] + data = Person.objects().none().order_by("name").aggregate(pipeline) + + assert list(data) == [] + if __name__ == "__main__": unittest.main()