Skip to content

Commit 01c1e42

Browse files
authored
Merge pull request #6 from iainb/batch-size
feat: noticket - add batch_size support to QuerySet
2 parents d45d6d5 + 90d98b2 commit 01c1e42

File tree

3 files changed

+79
-2
lines changed

3 files changed

+79
-2
lines changed

mongoengine/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
__all__ = (document.__all__ + fields.__all__ + connection.__all__ +
1313
queryset.__all__ + signals.__all__)
1414

15-
VERSION = (0, 6, 21)
15+
VERSION = (0, 6, 22)
1616

1717

1818
def get_version():

mongoengine/queryset.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ def __init__(self, document, collection):
351351
self._limit = None
352352
self._skip = None
353353
self._hint = -1 # Using -1 as None is a valid value for hint
354+
self._batch_size = None
354355

355356
def clone(self):
356357
"""Creates a copy of the current :class:`~mongoengine.queryset.QuerySet`
@@ -361,7 +362,7 @@ def clone(self):
361362

362363
copy_props = ('_initial_query', '_query_obj', '_where_clause',
363364
'_loaded_fields', '_ordering',
364-
'_limit', '_skip', '_hint',
365+
'_limit', '_skip', '_hint', '_batch_size',
365366
'_read_preference',)
366367

367368
for prop in copy_props:
@@ -522,6 +523,9 @@ def _cursor(self):
522523
if self._hint != -1:
523524
self._cursor_obj.hint(self._hint)
524525

526+
if self._batch_size is not None:
527+
self._cursor_obj.batch_size(self._batch_size)
528+
525529
return self._cursor_obj
526530

527531
@classmethod
@@ -1014,6 +1018,21 @@ def hint(self, index=None):
10141018
self._hint = index
10151019
return self
10161020

1021+
def batch_size(self, size):
1022+
"""Limit the number of documents returned in a single batch (each batch
1023+
requires a round trip to the server).
1024+
1025+
1026+
See http://api.mongodb.com/python/current/api/pymongo/cursor.html#pymongo.cursor.Cursor.batch_size
1027+
for details.
1028+
:param size: desired size of each batch.
1029+
"""
1030+
if self._cursor_obj is not None:
1031+
self._cursor_obj.batch_size(size)
1032+
1033+
self._batch_size = size
1034+
return self
1035+
10171036
def __getitem__(self, key):
10181037
"""Support skip and limit using getitem and slicing syntax.
10191038
"""

tests/queryset.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2892,6 +2892,64 @@ def test_scalar_cursor_behaviour(self):
28922892
pks = self.Person.objects.order_by('age').scalar('pk')[1:3]
28932893
self.assertEqual("[u'A1', u'A2']", "%s" % sorted(self.Person.objects.scalar('name').in_bulk(list(pks)).values()))
28942894

2895+
def test_batch_size(self):
2896+
"""Ensure that batch_size works."""
2897+
class A(Document):
2898+
s = StringField()
2899+
2900+
A.drop_collection()
2901+
2902+
for i in range(100):
2903+
A.objects.create(s=str(i))
2904+
2905+
# test iterating over the result set
2906+
cnt = 0
2907+
for a in A.objects.batch_size(10):
2908+
cnt += 1
2909+
self.assertEqual(cnt, 100)
2910+
2911+
# test chaining
2912+
qs = A.objects.all()
2913+
qs = qs.limit(10).batch_size(20).skip(91)
2914+
cnt = 0
2915+
for a in qs:
2916+
cnt += 1
2917+
self.assertEqual(cnt, 9)
2918+
2919+
# test chaining and iteration with small batch size
2920+
qs = A.objects.all()
2921+
qs = qs.limit(10).batch_size(4).skip(91)
2922+
cnt = 0
2923+
for a in qs:
2924+
cnt += 1
2925+
self.assertEqual(cnt, 9)
2926+
2927+
# test invalid batch size
2928+
qs = A.objects.batch_size(-1)
2929+
with self.assertRaises(ValueError):
2930+
list(qs)
2931+
2932+
def test_modify_evaluated_query_with_batch_size(self):
2933+
class Number(Document):
2934+
n = IntField()
2935+
2936+
Number.drop_collection()
2937+
2938+
for i in xrange(1, 101):
2939+
t = Number(n=i)
2940+
t.save()
2941+
2942+
test = Number.objects
2943+
self.assertEqual(test.count(), 100)
2944+
2945+
test = test.filter(n__gt=11)
2946+
self.assertEqual(test.count(), 89)
2947+
2948+
test = test.batch_size(10)
2949+
self.assertEqual(len(list(test)), 89)
2950+
2951+
Number.drop_collection()
2952+
28952953

28962954
class QTest(unittest.TestCase):
28972955

0 commit comments

Comments
 (0)