diff --git a/pymongo/collection.py b/pymongo/collection.py index 9dd5e248f..135f45ef0 100644 --- a/pymongo/collection.py +++ b/pymongo/collection.py @@ -1173,9 +1173,6 @@ class Collection(common.BaseObject): results to the client without waiting for the client to request each batch, reducing latency. See notes on compatibility below. - - `raw_batches` (optional): If True, use the legacy wire protocol to - query MongoDB, and use a :class:`~pymongo.cursor.RawBSONCursor` - that returns entire batches of documents as raw BSON streams. - `sort` (optional): a list of (key, direction) pairs specifying the sort order for this query. See :meth:`~pymongo.cursor.Cursor.sort` for details. @@ -1245,7 +1242,7 @@ class Collection(common.BaseObject): .. versionchanged:: 3.5 Added the options `return_key`, `show_record_id`, `snapshot`, `hint`, `max_time_ms`, `max_scan`, `min`, `max`, and `comment`. - Deprecated the option `modifiers`. Support the `raw_batches` option. + Deprecated the option `modifiers`. .. versionchanged:: 3.4 Support the `collation` option. @@ -1279,10 +1276,27 @@ class Collection(common.BaseObject): .. mongodoc:: find """ - if kwargs.pop('raw_batches', False): - return RawBSONCursor(self, *args, **kwargs) - else: - return Cursor(self, *args, **kwargs) + return Cursor(self, *args, **kwargs) + + def find_raw(self, *args, **kwargs): + """Query the database and retrieve batches of raw BSON. + + Takes the same parameters as :meth:`find` but returns a + :class:`~pymongo.cursor.RawBSONCursor`. + + This example demonstrates how to work with raw batches, but in practice + raw batches should be passed to an external library that can decode + BSON into another data type, rather than used with PyMongo's + :mod:`bson` module. + + >>> import bson + >>> cursor = db.test.find_raw() + >>> for batch in cursor: + ... print(bson.decode_all(batch)) + + .. versionadded:: 3.6 + """ + return RawBSONCursor(self, *args, **kwargs) def parallel_scan(self, num_cursors, **kwargs): """Scan this entire collection in parallel. diff --git a/pymongo/cursor.py b/pymongo/cursor.py index e8127d15e..2165353ad 100644 --- a/pymongo/cursor.py +++ b/pymongo/cursor.py @@ -1235,22 +1235,11 @@ class RawBSONCursor(Cursor): def __init__(self, *args, **kwargs): """Create a new cursor / iterator over raw batches of BSON data. - Should not be called directly by application developers. Pass - ``raw_batches=True`` to :meth:`~pymongo.collection.Collection.find` + Should not be called directly by application developers - + see :meth:`~pymongo.collection.Collection.find_raw` instead. - This example demonstrates how to work with raw batches, but in practice - raw batches should be passed to an external library that can decode - BSON into another data type, rather than used with PyMongo's - :mod:`bson` module. - - >>> import bson - >>> cursor = db.test.find(raw_batches=True) - >>> for batch in cursor: - ... print(bson.decode_all(batch)) - .. mongodoc:: cursors - """ if kwargs.get('manipulate'): raise InvalidOperation( diff --git a/test/test_cursor.py b/test/test_cursor.py index 4cd097070..445166fc9 100644 --- a/test/test_cursor.py +++ b/test/test_cursor.py @@ -1338,23 +1338,23 @@ class TestCursor(IntegrationTest): class TestRawBSONCursor(IntegrationTest): - def test_raw_batches(self): + def test_find_raw(self): c = self.db.test c.drop() docs = [{'_id': i, 'x': 3.0 * i} for i in range(10)] c.insert_many(docs) - batches = list(c.find(raw_batches=True).sort('_id')) + batches = list(c.find_raw().sort('_id')) self.assertEqual(1, len(batches)) self.assertEqual(docs, decode_all(batches[0])) def test_explain(self): c = self.db.test c.insert_one({}) - explanation = c.find(raw_batches=True).explain() + explanation = c.find_raw().explain() self.assertIsInstance(explanation, dict) def test_clone(self): - cursor = self.db.test.find(raw_batches=True) + cursor = self.db.test.find_raw() # Copy of a RawBSONCursor is also a RawBSONCursor, not a Cursor. self.assertIsInstance(next(cursor.clone()), bytes) self.assertIsInstance(next(copy.copy(cursor)), bytes) @@ -1364,42 +1364,39 @@ class TestRawBSONCursor(IntegrationTest): c = self.db.test c.drop() c.insert_many({'_id': i} for i in range(200)) - result = b''.join( - c.find(raw_batches=True, cursor_type=CursorType.EXHAUST)) - + result = b''.join(c.find_raw(cursor_type=CursorType.EXHAUST)) self.assertEqual([{'_id': i} for i in range(200)], decode_all(result)) def test_server_error(self): with self.assertRaises(OperationFailure) as exc: - next(self.db.test.find({'x': {'$bad': 1}}, raw_batches=True)) + next(self.db.test.find_raw({'x': {'$bad': 1}})) # The server response was decoded, not left raw. self.assertIsInstance(exc.exception.details, dict) def test_get_item(self): with self.assertRaises(InvalidOperation): - self.db.test.find(raw_batches=True)[0] + self.db.test.find_raw()[0] @client_context.require_version_min(3, 4) def test_collation(self): - next(self.db.test.find(collation=Collation('en_US'), raw_batches=True)) + next(self.db.test.find_raw(collation=Collation('en_US'))) @client_context.require_version_max(3, 2) def test_collation_error(self): with self.assertRaises(ConfigurationError): - next(self.db.test.find(collation=Collation('en_US'), - raw_batches=True)) + next(self.db.test.find_raw(collation=Collation('en_US'))) @client_context.require_version_min(3, 2) def test_read_concern(self): c = self.db.get_collection("test", read_concern=ReadConcern("majority")) - next(c.find(raw_batches=True)) + next(c.find_raw()) @client_context.require_version_max(3, 1) def test_read_concern_error(self): c = self.db.get_collection("test", read_concern=ReadConcern("majority")) with self.assertRaises(ConfigurationError): - next(c.find(raw_batches=True)) + next(c.find_raw()) def test_monitoring(self): listener = EventListener() @@ -1409,7 +1406,7 @@ class TestRawBSONCursor(IntegrationTest): c.insert_many([{'_id': i} for i in range(10)]) listener.results.clear() - cursor = c.find(raw_batches=True, batch_size=4) + cursor = c.find_raw(batch_size=4) # First raw batch of 4 documents. next(cursor)