Ejemplo n.º 1
0
    def test_create_geohaystack_index(self):
        """Ensure that geohaystack indexes can be created"""
        class Place(Document):
            location = DictField()
            name = StringField()

        if PYMONGO_VERSION >= (4, ):
            expected_error = NotImplementedError
        elif get_mongodb_version() >= (4, 9):
            expected_error = OperationFailure
        else:
            expected_error = None

        # This test can be removed when pymongo 3.x is no longer supported
        if expected_error:
            with pytest.raises(expected_error):
                Place.create_index(
                    {"fields": (")location.point", "name")},
                    bucketSize=10,
                )
        else:
            Place.create_index({"fields": (")location.point", "name")},
                               bucketSize=10)
            info = Place._get_collection().index_information()
            info = [value["key"] for key, value in info.items()]
            assert [("location.point", "geoHaystack"), ("name", 1)] in info
Ejemplo n.º 2
0
    def _inner(*args, **kwargs):
        mongodb_v = get_mongodb_version()
        if oper(mongodb_v, mongo_version_req):
            return func(*args, **kwargs)

        pretty_version = ".".join(str(n) for n in mongo_version_req)
        pytest.skip(f"Needs MongoDB v{pretty_version}+")
Ejemplo n.º 3
0
    def _inner(*args, **kwargs):
        mongodb_v = get_mongodb_version()
        if oper(mongodb_v, mongo_version_req):
            return func(*args, **kwargs)

        raise SkipTest('Needs MongoDB v{}+'.format('.'.join(
            str(n) for n in mongo_version_req)))
Ejemplo n.º 4
0
    def test_covered_index(self):
        """Ensure that covered indexes can be used
        """
        IS_MONGODB_3 = get_mongodb_version() >= MONGODB_3

        class Test(Document):
            a = IntField()
            b = IntField()

            meta = {'indexes': ['a'], 'allow_inheritance': False}

        Test.drop_collection()

        obj = Test(a=1)
        obj.save()

        # Need to be explicit about covered indexes as mongoDB doesn't know if
        # the documents returned might have more keys in that here.
        query_plan = Test.objects(id=obj.id).exclude('a').explain()
        if not IS_MONGODB_3:
            self.assertFalse(query_plan['indexOnly'])
        else:
            self.assertEqual(
                query_plan.get('queryPlanner').get('winningPlan').get(
                    'inputStage').get('stage'), 'IDHACK')

        query_plan = Test.objects(id=obj.id).only('id').explain()
        if not IS_MONGODB_3:
            self.assertTrue(query_plan['indexOnly'])
        else:
            self.assertEqual(
                query_plan.get('queryPlanner').get('winningPlan').get(
                    'inputStage').get('stage'), 'IDHACK')

        query_plan = Test.objects(a=1).only('a').exclude('id').explain()
        if not IS_MONGODB_3:
            self.assertTrue(query_plan['indexOnly'])
        else:
            self.assertEqual(
                query_plan.get('queryPlanner').get('winningPlan').get(
                    'inputStage').get('stage'), 'IXSCAN')
            self.assertEqual(
                query_plan.get('queryPlanner').get('winningPlan').get('stage'),
                'PROJECTION')

        query_plan = Test.objects(a=1).explain()
        if not IS_MONGODB_3:
            self.assertFalse(query_plan['indexOnly'])
        else:
            self.assertEqual(
                query_plan.get('queryPlanner').get('winningPlan').get(
                    'inputStage').get('stage'), 'IXSCAN')
            self.assertEqual(
                query_plan.get('queryPlanner').get('winningPlan').get('stage'),
                'FETCH')
Ejemplo n.º 5
0
    def test_keys_with_dots_or_dollars(self):
        class BlogPost(Document):
            info = DictField()

        BlogPost.drop_collection()

        post = BlogPost()

        post.info = {"$title": "test"}
        with pytest.raises(ValidationError):
            post.validate()

        post.info = {"nested": {"$title": "test"}}
        with pytest.raises(ValidationError):
            post.validate()

        post.info = {"$title.test": "test"}
        with pytest.raises(ValidationError):
            post.validate()

        post.info = {"nested": {"the.title": "test"}}
        if get_mongodb_version() < MONGODB_36:
            # MongoDB < 3.6 rejects dots
            # To avoid checking the mongodb version from the DictField class
            # we rely on MongoDB to reject the data during the save
            post.validate()
            with pytest.raises(InvalidDocument):
                post.save()
        else:
            post.validate()

        post.info = {"dollar_and_dot": {"te$st.test": "test"}}
        if get_mongodb_version() < MONGODB_36:
            post.validate()
            with pytest.raises(InvalidDocument):
                post.save()
        else:
            post.validate()
Ejemplo n.º 6
0
    def setUp(self):
        self.connection = connect(db='mongoenginetest')
        self.db = get_db()
        self.mongodb_version = get_mongodb_version()

        class Person(Document):
            name = StringField()
            age = IntField()

            non_field = True

            meta = {"allow_inheritance": True}

        self.Person = Person
Ejemplo n.º 7
0
    def setUp(self):
        self.connection = connect(db='mongoenginetest')
        self.db = get_db()
        self.mongodb_version = get_mongodb_version()

        class Person(Document):
            name = StringField()
            age = IntField()

            non_field = True

            meta = {"allow_inheritance": True}

        self.Person = Person
Ejemplo n.º 8
0
    def test_covered_index(self):
        """Ensure that covered indexes can be used
        """
        IS_MONGODB_3 = get_mongodb_version() >= MONGODB_3

        class Test(Document):
            a = IntField()
            b = IntField()

            meta = {
                'indexes': ['a'],
                'allow_inheritance': False
            }

        Test.drop_collection()

        obj = Test(a=1)
        obj.save()

        # Need to be explicit about covered indexes as mongoDB doesn't know if
        # the documents returned might have more keys in that here.
        query_plan = Test.objects(id=obj.id).exclude('a').explain()
        if not IS_MONGODB_3:
            self.assertFalse(query_plan['indexOnly'])
        else:
            self.assertEqual(query_plan.get('queryPlanner').get('winningPlan').get('inputStage').get('stage'), 'IDHACK')

        query_plan = Test.objects(id=obj.id).only('id').explain()
        if not IS_MONGODB_3:
            self.assertTrue(query_plan['indexOnly'])
        else:
            self.assertEqual(query_plan.get('queryPlanner').get('winningPlan').get('inputStage').get('stage'), 'IDHACK')

        query_plan = Test.objects(a=1).only('a').exclude('id').explain()
        if not IS_MONGODB_3:
            self.assertTrue(query_plan['indexOnly'])
        else:
            self.assertEqual(query_plan.get('queryPlanner').get('winningPlan').get('inputStage').get('stage'), 'IXSCAN')
            self.assertEqual(query_plan.get('queryPlanner').get('winningPlan').get('stage'), 'PROJECTION')

        query_plan = Test.objects(a=1).explain()
        if not IS_MONGODB_3:
            self.assertFalse(query_plan['indexOnly'])
        else:
            self.assertEqual(query_plan.get('queryPlanner').get('winningPlan').get('inputStage').get('stage'), 'IXSCAN')
            self.assertEqual(query_plan.get('queryPlanner').get('winningPlan').get('stage'), 'FETCH')
Ejemplo n.º 9
0
    def test_covered_index(self):
        """Ensure that covered indexes can be used"""
        class Test(Document):
            a = IntField()
            b = IntField()

            meta = {"indexes": ["a"], "allow_inheritance": False}

        Test.drop_collection()

        obj = Test(a=1)
        obj.save()

        # Need to be explicit about covered indexes as mongoDB doesn't know if
        # the documents returned might have more keys in that here.
        query_plan = Test.objects(id=obj.id).exclude("a").explain()
        assert (query_plan.get("queryPlanner").get("winningPlan").get(
            "inputStage").get("stage") == "IDHACK")

        query_plan = Test.objects(id=obj.id).only("id").explain()
        assert (query_plan.get("queryPlanner").get("winningPlan").get(
            "inputStage").get("stage") == "IDHACK")

        query_plan = Test.objects(a=1).only("a").exclude("id").explain()
        assert (query_plan.get("queryPlanner").get("winningPlan").get(
            "inputStage").get("stage") == "IXSCAN")
        mongo_db = get_mongodb_version()
        PROJECTION_STR = "PROJECTION" if mongo_db < MONGODB_42 else "PROJECTION_COVERED"
        assert (query_plan.get("queryPlanner").get("winningPlan").get("stage")
                == PROJECTION_STR)

        query_plan = Test.objects(a=1).explain()
        assert (query_plan.get("queryPlanner").get("winningPlan").get(
            "inputStage").get("stage") == "IXSCAN")
        assert query_plan.get("queryPlanner").get("winningPlan").get(
            "stage") == "FETCH"
Ejemplo n.º 10
0
    def test_general_things(self):
        """Ensure that dict types work as expected."""
        class BlogPost(Document):
            info = DictField()

        BlogPost.drop_collection()

        post = BlogPost()
        post.info = "my post"
        with pytest.raises(ValidationError):
            post.validate()

        post.info = ["test", "test"]
        with pytest.raises(ValidationError):
            post.validate()

        post.info = {"$title": "test"}
        with pytest.raises(ValidationError):
            post.validate()

        post.info = {"nested": {"$title": "test"}}
        with pytest.raises(ValidationError):
            post.validate()

        post.info = {"$title.test": "test"}
        with pytest.raises(ValidationError):
            post.validate()

        post.info = {1: "test"}
        with pytest.raises(ValidationError):
            post.validate()

        post.info = {"nested": {"the.title": "test"}}
        if get_mongodb_version() < MONGODB_36:
            with pytest.raises(ValidationError):
                post.validate()
        else:
            post.validate()

        post.info = {"dollar_and_dot": {"te$st.test": "test"}}
        if get_mongodb_version() < MONGODB_36:
            with pytest.raises(ValidationError):
                post.validate()
        else:
            post.validate()

        post.info = {"title": "test"}
        post.save()

        post = BlogPost()
        post.info = {"title": "dollar_sign", "details": {"te$t": "test"}}
        post.save()

        post = BlogPost()
        post.info = {"details": {"test": "test"}}
        post.save()

        post = BlogPost()
        post.info = {"details": {"test": 3}}
        post.save()

        assert BlogPost.objects.count() == 4
        assert BlogPost.objects.filter(info__title__exact="test").count() == 1
        assert BlogPost.objects.filter(
            info__details__test__exact="test").count() == 1

        post = BlogPost.objects.filter(
            info__title__exact="dollar_sign").first()
        assert "te$t" in post["info"]["details"]

        # Confirm handles non strings or non existing keys
        assert BlogPost.objects.filter(
            info__details__test__exact=5).count() == 0
        assert BlogPost.objects.filter(
            info__made_up__test__exact="test").count() == 0

        post = BlogPost.objects.create(info={"title": "original"})
        post.info.update({"title": "updated"})
        post.save()
        post.reload()
        assert "updated" == post.info["title"]

        post.info.setdefault("authors", [])
        post.save()
        post.reload()
        assert [] == post.info["authors"]
Ejemplo n.º 11
0
    def _inner(*args, **kwargs):
        mongodb_v = get_mongodb_version()
        if oper(mongodb_v, mongo_version_req):
            return func(*args, **kwargs)

        raise SkipTest('Needs MongoDB v{}+'.format('.'.join(str(n) for n in mongo_version_req)))