Skip to content

Commit 6c4e4b5

Browse files
committed
PYTHON-1065 - Support 1 for batch_size with MongoDB >= 3.2
1 parent e873e27 commit 6c4e4b5

File tree

4 files changed

+30
-14
lines changed

4 files changed

+30
-14
lines changed

pymongo/cursor.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ def batch_size(self, batch_size):
426426
raise ValueError("batch_size must be >= 0")
427427
self.__check_okay_to_chain()
428428

429-
self.__batch_size = batch_size == 1 and 2 or batch_size
429+
self.__batch_size = batch_size
430430
return self
431431

432432
def skip(self, skip):
@@ -999,17 +999,10 @@ def _refresh(self):
999999
return len(self.__data)
10001000

10011001
if self.__id is None: # Query
1002-
ntoreturn = self.__batch_size
1003-
if self.__limit:
1004-
if self.__batch_size:
1005-
ntoreturn = min(self.__limit, self.__batch_size)
1006-
else:
1007-
ntoreturn = self.__limit
10081002
self.__send_message(_Query(self.__query_flags,
10091003
self.__collection.database.name,
10101004
self.__collection.name,
10111005
self.__skip,
1012-
ntoreturn,
10131006
self.__query_spec(),
10141007
self.__projection,
10151008
self.__codec_options,

pymongo/helpers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,8 @@ def _first_batch(sock_info, db, coll, query, ntoreturn,
240240
slave_ok, codec_options, read_preference, cmd, listeners):
241241
"""Simple query helper for retrieving a first (and possibly only) batch."""
242242
query = _Query(
243-
0, db, coll, 0, ntoreturn, query, None,
244-
codec_options, read_preference, 0, 0, DEFAULT_READ_CONCERN)
243+
0, db, coll, 0, query, None,
244+
codec_options, read_preference, ntoreturn, 0, DEFAULT_READ_CONCERN)
245245

246246
name = next(iter(cmd))
247247
duration = None

pymongo/message.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,18 +214,17 @@ def _gen_get_more_command(cursor_id, coll, batch_size, max_await_time_ms):
214214
class _Query(object):
215215
"""A query operation."""
216216

217-
__slots__ = ('flags', 'db', 'coll', 'ntoskip', 'ntoreturn', 'spec',
217+
__slots__ = ('flags', 'db', 'coll', 'ntoskip', 'spec',
218218
'fields', 'codec_options', 'read_preference', 'limit',
219219
'batch_size', 'name', 'read_concern')
220220

221-
def __init__(self, flags, db, coll, ntoskip, ntoreturn, spec, fields,
221+
def __init__(self, flags, db, coll, ntoskip, spec, fields,
222222
codec_options, read_preference, limit,
223223
batch_size, read_concern):
224224
self.flags = flags
225225
self.db = db
226226
self.coll = coll
227227
self.ntoskip = ntoskip
228-
self.ntoreturn = ntoreturn
229228
self.spec = spec
230229
self.fields = fields
231230
self.codec_options = codec_options
@@ -260,12 +259,21 @@ def get_message(self, set_slave_ok, is_mongos, use_cmd=False):
260259

261260
ns = _UJOIN % (self.db, self.coll)
262261
spec = self.spec
263-
ntoreturn = self.ntoreturn
264262

265263
if use_cmd:
266264
ns = _UJOIN % (self.db, "$cmd")
267265
spec = self.as_command()[0]
268266
ntoreturn = -1 # All DB commands return 1 document
267+
else:
268+
# OP_QUERY treats ntoreturn of -1 and 1 the same, return
269+
# one document and close the cursor. We have to use 2 for
270+
# batch size if 1 is specified.
271+
ntoreturn = self.batch_size == 1 and 2 or self.batch_size
272+
if self.limit:
273+
if ntoreturn:
274+
ntoreturn = min(self.limit, ntoreturn)
275+
else:
276+
ntoreturn = self.limit
269277

270278
if is_mongos:
271279
spec = _maybe_add_read_preference(spec,

test/test_cursor.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,21 @@ def cursor_count(cursor, expected_count):
540540
cursor_count(db.test.find().batch_size(100).limit(10), 10)
541541
cursor_count(db.test.find().batch_size(500).limit(10), 10)
542542

543+
cur = db.test.find().batch_size(1)
544+
next(cur)
545+
if client_context.version.at_least(3, 1, 9):
546+
# find command batchSize should be 1
547+
self.assertEqual(0, len(cur._Cursor__data))
548+
else:
549+
# OP_QUERY ntoreturn should be 2
550+
self.assertEqual(1, len(cur._Cursor__data))
551+
next(cur)
552+
self.assertEqual(0, len(cur._Cursor__data))
553+
next(cur)
554+
self.assertEqual(0, len(cur._Cursor__data))
555+
next(cur)
556+
self.assertEqual(0, len(cur._Cursor__data))
557+
543558
def test_limit_and_batch_size(self):
544559
db = self.db
545560
db.test.drop()

0 commit comments

Comments
 (0)