PYTHON-821 - Implement insert_many
This commit is contained in:
parent
4d6bdb1097
commit
f9243f0ad9
@ -29,7 +29,7 @@ from bson.son import SON
|
||||
from pymongo import (common,
|
||||
helpers,
|
||||
message)
|
||||
from pymongo.bulk import (BulkOperationBuilder, _Bulk)
|
||||
from pymongo.bulk import BulkOperationBuilder, _Bulk
|
||||
from pymongo.command_cursor import CommandCursor
|
||||
from pymongo.cursor import Cursor
|
||||
from pymongo.errors import ConfigurationError, InvalidName, OperationFailure
|
||||
@ -495,6 +495,39 @@ class Collection(common.BaseObject):
|
||||
return InsertOneResult(self.__insert(document),
|
||||
self.write_concern.acknowledged)
|
||||
|
||||
def insert_many(self, documents, ordered=True):
|
||||
"""Insert a list of documents.
|
||||
|
||||
:Parameters:
|
||||
- `documents`: A list of documents to insert.
|
||||
- `ordered` (optional): If ``True`` (the default) documents will be
|
||||
inserted on the server serially, in the order provided. If an error
|
||||
occurs all remaining inserts are aborted. If ``False``, documents
|
||||
will be inserted on the server in arbitrary order, possibly in
|
||||
parallel, and all document inserts will be attempted.
|
||||
|
||||
:Returns:
|
||||
An instance of :class:`~pymongo.results.InsertManyResult`.
|
||||
"""
|
||||
if not isinstance(documents, list) or not documents:
|
||||
raise TypeError("documents must be a non-empty list")
|
||||
inserted_ids = []
|
||||
def gen():
|
||||
"""A generator that validates documents and handles _ids."""
|
||||
for document in documents:
|
||||
if not isinstance(document, collections.MutableMapping):
|
||||
raise TypeError("document must be a dict or other "
|
||||
"subclass of collections.MutableMapping")
|
||||
if "_id" not in document:
|
||||
document["_id"] = ObjectId()
|
||||
inserted_ids.append(document["_id"])
|
||||
yield (_INSERT, document)
|
||||
|
||||
blk = _Bulk(self, ordered)
|
||||
blk.ops = [doc for doc in gen()]
|
||||
blk.execute(self.write_concern.document)
|
||||
return InsertManyResult(inserted_ids, self.write_concern.acknowledged)
|
||||
|
||||
def __insert(self, docs, ordered=True,
|
||||
check_keys=True, manipulate=False, write_concern=None):
|
||||
"""Internal insert helper."""
|
||||
|
||||
@ -52,6 +52,28 @@ class InsertOneResult(_WriteResult):
|
||||
return self.__inserted_id
|
||||
|
||||
|
||||
class InsertManyResult(_WriteResult):
|
||||
"""The return type for :meth:`~pymongo.collection.Collection.insert_many`.
|
||||
"""
|
||||
|
||||
__slots__ = ("__inserted_ids", "__acknowledged")
|
||||
|
||||
def __init__(self, inserted_ids, acknowledged):
|
||||
self.__inserted_ids = inserted_ids
|
||||
super(InsertManyResult, self).__init__(acknowledged)
|
||||
|
||||
@property
|
||||
def inserted_ids(self):
|
||||
"""A list of _ids of the inserted documents, in the order provided.
|
||||
|
||||
.. note:: If ``False`` is passed for the `ordered` parameter to
|
||||
:meth:`~pymongo.collection.Collection.insert_many` the server
|
||||
may have inserted the documents in a different order than what
|
||||
is presented here.
|
||||
"""
|
||||
return self.__inserted_ids
|
||||
|
||||
|
||||
class UpdateResult(_WriteResult):
|
||||
"""The return type for :meth:`~pymongo.collection.Collection.update_one`
|
||||
and :meth:`~pymongo.collection.Collection.update_many`"""
|
||||
|
||||
@ -48,7 +48,7 @@ from pymongo.errors import (ConfigurationError,
|
||||
WTimeoutError)
|
||||
from pymongo.options import ReturnDocument
|
||||
from pymongo.read_preferences import ReadPreference
|
||||
from pymongo.results import DeleteResult, InsertOneResult, UpdateResult
|
||||
from pymongo.results import *
|
||||
from pymongo.son_manipulator import SONManipulator
|
||||
from pymongo.write_concern import WriteConcern
|
||||
from test.test_client import IntegrationTest
|
||||
@ -639,6 +639,42 @@ class TestCollection(IntegrationTest):
|
||||
# The insert failed duplicate key...
|
||||
self.assertEqual(2, db.test.count())
|
||||
|
||||
def test_insert_many(self):
|
||||
db = self.db
|
||||
db.test.drop()
|
||||
|
||||
docs = [{} for _ in range(5)]
|
||||
result = db.test.insert_many(docs)
|
||||
self.assertTrue(isinstance(result, InsertManyResult))
|
||||
self.assertTrue(isinstance(result.inserted_ids, list))
|
||||
self.assertEqual(5, len(result.inserted_ids))
|
||||
for doc in docs:
|
||||
_id = doc["_id"]
|
||||
self.assertTrue(isinstance(_id, ObjectId))
|
||||
self.assertTrue(_id in result.inserted_ids)
|
||||
self.assertEqual(1, db.test.count({'_id': _id}))
|
||||
self.assertTrue(result.acknowledged)
|
||||
|
||||
docs = [{"_id": i} for i in range(5)]
|
||||
result = db.test.insert_many(docs)
|
||||
self.assertTrue(isinstance(result, InsertManyResult))
|
||||
self.assertTrue(isinstance(result.inserted_ids, list))
|
||||
self.assertEqual(5, len(result.inserted_ids))
|
||||
for doc in docs:
|
||||
_id = doc["_id"]
|
||||
self.assertTrue(isinstance(_id, int))
|
||||
self.assertTrue(_id in result.inserted_ids)
|
||||
self.assertEqual(1, db.test.count({"_id": _id}))
|
||||
self.assertTrue(result.acknowledged)
|
||||
|
||||
db = db.connection.get_database(db.name,
|
||||
write_concern=WriteConcern(w=0))
|
||||
docs = [{} for _ in range(5)]
|
||||
result = db.test.insert_many(docs)
|
||||
self.assertTrue(isinstance(result, InsertManyResult))
|
||||
self.assertFalse(result.acknowledged)
|
||||
self.assertEqual(15, db.test.count())
|
||||
|
||||
def test_generator_insert(self):
|
||||
db = self.db
|
||||
db.test.remove({})
|
||||
|
||||
Loading…
Reference in New Issue
Block a user