diff --git a/README.rst b/README.rst index 47ebcd7f..24df3441 100644 --- a/README.rst +++ b/README.rst @@ -75,12 +75,11 @@ Quick example Get it now:: - $ pip install umongo - $ pip install my-mongo-driver # Note you have to manually install the mongodb driver + $ pip install umongo # This installs umongo with pymongo + $ pip install my-mongo-driver # Other MongoDB drivers must be installed manually Or to get it along with the MongoDB driver you're planing to use:: - $ pip install umongo[pymongo] # choose - $ pip install umongo[motor] # one - $ pip install umongo[txmongo] # of - $ pip install umongo[mongomock] # them ;-) + $ pip install umongo[motor] + $ pip install umongo[txmongo] + $ pip install umongo[mongomock] diff --git a/docs/userguide.rst b/docs/userguide.rst index 6eb31525..22114567 100644 --- a/docs/userguide.rst +++ b/docs/userguide.rst @@ -280,9 +280,9 @@ Now we can define & register documents, then work with them: False >>> DogInstance2Impl = instance2.register(Dog) >>> DogInstance1Impl().commit() - >>> DogInstance1Impl.find().count() + >>> DogInstance1Impl.count_documents() 1 - >>> DogInstance2Impl.find().count() + >>> DogInstance2Impl.count_documents() 0 .. note:: diff --git a/setup.py b/setup.py index 6ed3885f..a9a0cbe1 100755 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ requirements = [ "marshmallow>=2.6.0", "python-dateutil>=2.5.0", - "pymongo>=3.2.0", + "pymongo>=3.7.0", ] setup( diff --git a/tests/frameworks/test_pymongo.py b/tests/frameworks/test_pymongo.py index 56691963..8d5d3f7e 100644 --- a/tests/frameworks/test_pymongo.py +++ b/tests/frameworks/test_pymongo.py @@ -84,17 +84,17 @@ def test_delete(self, classroom_model): with pytest.raises(exceptions.NotCreatedError): john.delete() john.commit() - assert Student.collection.find().count() == 1 + assert Student.count_documents() == 1 ret = john.delete() assert isinstance(ret, DeleteResult) assert not john.is_created - assert Student.collection.find().count() == 0 + assert Student.count_documents() == 0 with pytest.raises(exceptions.NotCreatedError): john.delete() # Can re-commit the document in database john.commit() assert john.is_created - assert Student.collection.find().count() == 1 + assert Student.count_documents() == 1 # Test conditional delete with pytest.raises(exceptions.DeleteError): john.delete(conditions={'name': 'Bad Name'}) @@ -123,11 +123,10 @@ def test_cursor(self, classroom_model): Student.collection.drop() for i in range(10): Student(name='student-%s' % i).commit() - cursor = Student.find(limit=5, skip=6) - assert cursor.count() == 10 - assert cursor.count(with_limit_and_skip=True) == 4 + assert Student.count_documents() == 10 + assert Student.count_documents(limit=5, skip=6) == 4 names = [] - for elem in cursor: + for elem in Student.find(limit=5, skip=6): assert isinstance(elem, Student) names.append(elem.name) assert sorted(names) == ['student-%s' % i for i in range(6, 10)] @@ -577,10 +576,10 @@ class InheritanceSearchChild2(InheritanceSearchParent): InheritanceSearchChild1Child(pf=1, sc1f=1).commit() InheritanceSearchChild2(pf=2, c2f=2).commit() - assert InheritanceSearchParent.find().count() == 4 - assert InheritanceSearchChild1.find().count() == 2 - assert InheritanceSearchChild1Child.find().count() == 1 - assert InheritanceSearchChild2.find().count() == 1 + assert InheritanceSearchParent.count_documents() == 4 + assert InheritanceSearchChild1.count_documents() == 2 + assert InheritanceSearchChild1Child.count_documents() == 1 + assert InheritanceSearchChild2.count_documents() == 1 res = InheritanceSearchParent.find_one({'sc1f': 1}) assert isinstance(res, InheritanceSearchChild1Child) @@ -631,10 +630,12 @@ class Book(Document): {'name': 'Jon I'} ]).commit() - assert Book.find({'title': 'The Hobbit'}).count() == 1 - assert Book.find({'author.name': {'$in': ['JK Rowling', 'JRR Tolkien']}}).count() == 2 - assert Book.find({'$and': [{'chapters.name': 'Roast Mutton'}, {'title': 'The Hobbit'}]}).count() == 1 - assert Book.find({'chapters.name': {'$all': ['Roast Mutton', 'A Short Rest']}}).count() == 1 + assert Book.count_documents({'title': 'The Hobbit'}) == 1 + assert Book.count_documents({'author.name': {'$in': ['JK Rowling', 'JRR Tolkien']}}) == 2 + assert Book.count_documents( + {'$and': [{'chapters.name': 'Roast Mutton'}, {'title': 'The Hobbit'}]}) == 1 + assert Book.count_documents( + {'chapters.name': {'$all': ['Roast Mutton', 'A Short Rest']}}) == 1 def test_pre_post_hooks(self, instance): diff --git a/umongo/frameworks/pymongo.py b/umongo/frameworks/pymongo.py index 4bfaa917..62239414 100644 --- a/umongo/frameworks/pymongo.py +++ b/umongo/frameworks/pymongo.py @@ -206,6 +206,17 @@ def find(cls, filter=None, *args, **kwargs): raw_cursor = cls.collection.find(*args, filter=filter, **kwargs) return cls.cursor_cls(cls, raw_cursor) + @classmethod + def count_documents(cls, filter=None, **kwargs): + """ + Get the number of documents in this collection. + + Unlike pymongo's collection.count_documents, filter is optional and + defaults to an empty filter. + """ + filter = cook_find_filter(cls, filter or {}) + return cls.collection.count_documents(filter, **kwargs) + @classmethod def ensure_indexes(cls): """