PYTHON-821 - Introduce results and options modules.
This commit is contained in:
parent
df4e5269b3
commit
b9cd7b627b
@ -16,17 +16,7 @@
|
||||
.. autodata:: pymongo.cursor.TAILABLE_AWAIT
|
||||
.. autodata:: pymongo.cursor.EXHAUST
|
||||
|
||||
.. autoclass:: pymongo.collection.InsertOneResult
|
||||
:members:
|
||||
|
||||
.. autoclass:: pymongo.collection.ReturnDocument
|
||||
|
||||
.. autoattribute:: Before
|
||||
:annotation:
|
||||
.. autoattribute:: After
|
||||
:annotation:
|
||||
|
||||
.. autoclass:: pymongo.collection.Collection(database, name[, create=False[, **kwargs]]])
|
||||
.. autoclass:: pymongo.collection.Collection(database, name[, create=False[, **kwargs]])
|
||||
|
||||
.. describe:: c[name] || c.name
|
||||
|
||||
|
||||
@ -40,8 +40,10 @@ Sub-modules:
|
||||
message
|
||||
mongo_client
|
||||
mongo_replica_set_client
|
||||
options
|
||||
pool
|
||||
read_preferences
|
||||
results
|
||||
son_manipulator
|
||||
cursor_manager
|
||||
uri_parser
|
||||
|
||||
6
doc/api/pymongo/options.rst
Normal file
6
doc/api/pymongo/options.rst
Normal file
@ -0,0 +1,6 @@
|
||||
:mod:`options` -- Option class definitions
|
||||
==========================================
|
||||
|
||||
.. automodule:: pymongo.options
|
||||
:synopsis: Option class definitions
|
||||
:members:
|
||||
6
doc/api/pymongo/results.rst
Normal file
6
doc/api/pymongo/results.rst
Normal file
@ -0,0 +1,6 @@
|
||||
:mod:`results` -- Result class definitions
|
||||
==========================================
|
||||
|
||||
.. automodule:: pymongo.results
|
||||
:synopsis: Result class definitions
|
||||
:members:
|
||||
237
pymongo/bulk.py
237
pymongo/bulk.py
@ -42,243 +42,6 @@ _WRITE_CONCERN_ERROR = 64
|
||||
_COMMANDS = ('insert', 'update', 'delete')
|
||||
|
||||
|
||||
class _WriteOp(object):
|
||||
"""Private base class for all write operations."""
|
||||
|
||||
__slots__ = ("_filter", "_doc", "_upsert")
|
||||
|
||||
def __init__(self, filter=None, doc=None, upsert=None):
|
||||
if filter is not None and not isinstance(filter, collections.Mapping):
|
||||
raise TypeError("filter must be a mapping type.")
|
||||
if upsert is not None and not isinstance(upsert, bool):
|
||||
raise TypeError("upsert must be True or False")
|
||||
self._filter = filter
|
||||
self._doc = doc
|
||||
self._upsert = upsert
|
||||
|
||||
|
||||
class InsertOne(_WriteOp):
|
||||
"""Represents an insert_one operation."""
|
||||
|
||||
def __init__(self, document):
|
||||
"""Create an InsertOne instance.
|
||||
|
||||
For use with :meth:`~pymongo.collection.Collection.bulk_write`.
|
||||
|
||||
:Parameters:
|
||||
- `document`: The document to insert. If the document is missing an
|
||||
_id field one will be added.
|
||||
"""
|
||||
super(InsertOne, self).__init__(doc=document)
|
||||
|
||||
def _add_to_bulk(self, bulkobj):
|
||||
"""Add this operation to the _Bulk instance `bulkobj`."""
|
||||
bulkobj.add_insert(self._doc)
|
||||
|
||||
def __repr__(self):
|
||||
return "InsertOne(%r)" % (self._doc,)
|
||||
|
||||
|
||||
class DeleteOne(_WriteOp):
|
||||
"""Represents a delete_one operation."""
|
||||
|
||||
def __init__(self, filter):
|
||||
"""Create a DeleteOne instance.
|
||||
|
||||
For use with :meth:`~pymongo.collection.Collection.bulk_write`.
|
||||
|
||||
:Parameters:
|
||||
- `filter`: A query that matches the document to delete.
|
||||
"""
|
||||
super(DeleteOne, self).__init__(filter)
|
||||
|
||||
def _add_to_bulk(self, bulkobj):
|
||||
"""Add this operation to the _Bulk instance `bulkobj`."""
|
||||
bulkobj.add_delete(self._filter, 1)
|
||||
|
||||
def __repr__(self):
|
||||
return "DeleteOne(%r)" % (self._filter,)
|
||||
|
||||
|
||||
class DeleteMany(_WriteOp):
|
||||
"""Represents a delete_many operation."""
|
||||
|
||||
def __init__(self, filter):
|
||||
"""Create a DeleteMany instance.
|
||||
|
||||
For use with :meth:`~pymongo.collection.Collection.bulk_write`.
|
||||
|
||||
:Parameters:
|
||||
- `filter`: A query that matches the documents to delete.
|
||||
"""
|
||||
super(DeleteMany, self).__init__(filter)
|
||||
|
||||
def _add_to_bulk(self, bulkobj):
|
||||
"""Add this operation to the _Bulk instance `bulkobj`."""
|
||||
bulkobj.add_delete(self._filter, 0)
|
||||
|
||||
def __repr__(self):
|
||||
return "DeleteMany(%r)" % (self._filter,)
|
||||
|
||||
|
||||
class ReplaceOne(_WriteOp):
|
||||
"""Represents a replace_one operation."""
|
||||
|
||||
def __init__(self, filter, replacement, upsert=False):
|
||||
"""Create a ReplaceOne instance.
|
||||
|
||||
For use with :meth:`~pymongo.collection.Collection.bulk_write`.
|
||||
|
||||
:Parameters:
|
||||
- `filter`: A query that matches the document to replace.
|
||||
- `replacement`: The new document.
|
||||
- `upsert` (optional): If ``True``, perform an insert if no documents
|
||||
match the filter.
|
||||
"""
|
||||
super(ReplaceOne, self).__init__(filter, replacement, upsert)
|
||||
|
||||
def _add_to_bulk(self, bulkobj):
|
||||
"""Add this operation to the _Bulk instance `bulkobj`."""
|
||||
bulkobj.add_replace(self._filter, self._doc, self._upsert)
|
||||
|
||||
def __repr__(self):
|
||||
return "ReplaceOne(%r, %r, %r)" % (self._filter,
|
||||
self._doc,
|
||||
self._upsert)
|
||||
|
||||
|
||||
class UpdateOne(_WriteOp):
|
||||
"""Represents an update_one operation."""
|
||||
|
||||
def __init__(self, filter, update, upsert=False):
|
||||
"""Represents an update_one operation.
|
||||
|
||||
For use with :meth:`~pymongo.collection.Collection.bulk_write`.
|
||||
|
||||
:Parameters:
|
||||
- `filter`: A query that matches the document to update.
|
||||
- `update`: The modifications to apply.
|
||||
- `upsert` (optional): If ``True``, perform an insert if no documents
|
||||
match the filter.
|
||||
"""
|
||||
super(UpdateOne, self).__init__(filter, update, upsert)
|
||||
|
||||
def _add_to_bulk(self, bulkobj):
|
||||
"""Add this operation to the _Bulk instance `bulkobj`."""
|
||||
bulkobj.add_update(self._filter, self._doc, False, self._upsert)
|
||||
|
||||
def __repr__(self):
|
||||
return "UpdateOne(%r, %r, %r)" % (self._filter,
|
||||
self._doc,
|
||||
self._upsert)
|
||||
|
||||
|
||||
class UpdateMany(_WriteOp):
|
||||
"""Represents an update_many operation."""
|
||||
|
||||
def __init__(self, filter, update, upsert=False):
|
||||
"""Create an UpdateMany instance.
|
||||
|
||||
For use with :meth:`~pymongo.collection.Collection.bulk_write`.
|
||||
|
||||
:Parameters:
|
||||
- `filter`: A query that matches the documents to update.
|
||||
- `update`: The modifications to apply.
|
||||
- `upsert` (optional): If ``True``, perform an insert if no documents
|
||||
match the filter.
|
||||
"""
|
||||
super(UpdateMany, self).__init__(filter, update, upsert)
|
||||
|
||||
def _add_to_bulk(self, bulkobj):
|
||||
"""Add this operation to the _Bulk instance `bulkobj`."""
|
||||
bulkobj.add_update(self._filter, self._doc, True, self._upsert)
|
||||
|
||||
def __repr__(self):
|
||||
return "UpdateMany(%r, %r, %r)" % (self._filter,
|
||||
self._doc,
|
||||
self._upsert)
|
||||
|
||||
|
||||
class BulkWriteResult(object):
|
||||
"""An object wrapper for bulk API write results."""
|
||||
|
||||
__slots__ = ("__bulk_api_result", "__acknowledged")
|
||||
|
||||
def __init__(self, bulk_api_result, acknowledged):
|
||||
"""Create a BulkWriteResult instance.
|
||||
|
||||
:Parameters:
|
||||
- `bulk_api_result`: A result dict from the bulk API
|
||||
- `acknowledged`: Was this write result acknowledged? If ``False``
|
||||
then all properties of this object will raise
|
||||
:exc:`~pymongo.errors.InvalidOperation`.
|
||||
"""
|
||||
self.__bulk_api_result = bulk_api_result
|
||||
self.__acknowledged = acknowledged
|
||||
|
||||
def __raise_if_unacknowledged(self, property_name):
|
||||
"""Raise an exception on property access if unacknowledged."""
|
||||
if not self.__acknowledged:
|
||||
raise InvalidOperation("A value for %s is not available when "
|
||||
"the write is unacknowledged. Check the "
|
||||
"acknowledged attribute to avoid this "
|
||||
"error." % (property_name,))
|
||||
|
||||
@property
|
||||
def bulk_api_result(self):
|
||||
"""The raw bulk API result."""
|
||||
return self.__bulk_api_result
|
||||
|
||||
@property
|
||||
def acknowledged(self):
|
||||
"""Is this the result of an acknowledged bulk write operation?"""
|
||||
return self.__acknowledged
|
||||
|
||||
@property
|
||||
def inserted_count(self):
|
||||
"""The number of documents inserted."""
|
||||
self.__raise_if_unacknowledged("inserted_count")
|
||||
return self.__bulk_api_result.get("nInserted")
|
||||
|
||||
@property
|
||||
def matched_count(self):
|
||||
"""The number of documents matched for an update."""
|
||||
self.__raise_if_unacknowledged("matched_count")
|
||||
return self.__bulk_api_result.get("nMatched")
|
||||
|
||||
@property
|
||||
def modified_count(self):
|
||||
"""The number of documents modified.
|
||||
|
||||
.. note:: modified_count is only reported by MongoDB 2.6 and later.
|
||||
When connected to an earlier server version, or in certain mixed
|
||||
version sharding configurations, this attribute will be set to
|
||||
``None``.
|
||||
"""
|
||||
self.__raise_if_unacknowledged("modified_count")
|
||||
return self.__bulk_api_result.get("nModified")
|
||||
|
||||
@property
|
||||
def deleted_count(self):
|
||||
"""The number of documents deleted."""
|
||||
self.__raise_if_unacknowledged("deleted_count")
|
||||
return self.__bulk_api_result.get("nRemoved")
|
||||
|
||||
@property
|
||||
def upserted_count(self):
|
||||
"""The number of documents upserted."""
|
||||
self.__raise_if_unacknowledged("upserted_count")
|
||||
return self.__bulk_api_result.get("nUpserted")
|
||||
|
||||
@property
|
||||
def upserted_ids(self):
|
||||
"""A map of operation index to the _id of the upserted document."""
|
||||
self.__raise_if_unacknowledged("upserted_ids")
|
||||
if self.__bulk_api_result:
|
||||
return dict((upsert["index"], upsert["_id"])
|
||||
for upsert in self.bulk_api_result["upserted"])
|
||||
|
||||
|
||||
class _Run(object):
|
||||
"""Represents a batch of write operations.
|
||||
"""
|
||||
|
||||
@ -29,16 +29,15 @@ from bson.son import SON
|
||||
from pymongo import (common,
|
||||
helpers,
|
||||
message)
|
||||
from pymongo.bulk import (BulkOperationBuilder,
|
||||
BulkWriteResult,
|
||||
_Bulk,
|
||||
_WriteOp)
|
||||
from pymongo.bulk import (BulkOperationBuilder, _Bulk)
|
||||
from pymongo.command_cursor import CommandCursor
|
||||
from pymongo.cursor import Cursor
|
||||
from pymongo.errors import ConfigurationError, InvalidName, OperationFailure
|
||||
from pymongo.helpers import _check_write_command_response, _command
|
||||
from pymongo.message import _INSERT, _UPDATE, _DELETE
|
||||
from pymongo.options import ReturnDocument, _WriteOp
|
||||
from pymongo.read_preferences import ReadPreference
|
||||
from pymongo.results import InsertOneResult, BulkWriteResult
|
||||
from pymongo.write_concern import WriteConcern
|
||||
|
||||
|
||||
@ -51,38 +50,6 @@ except ImportError:
|
||||
_NO_OBJ_ERROR = "No matching object found"
|
||||
|
||||
|
||||
class InsertOneResult(object):
|
||||
"""The return type for :meth:`Collection.insert_one`."""
|
||||
|
||||
__slots__ = ("__inserted_id", "__acknowledged")
|
||||
|
||||
def __init__(self, inserted_id, acknowledged):
|
||||
self.__inserted_id = inserted_id
|
||||
self.__acknowledged = acknowledged
|
||||
|
||||
@property
|
||||
def inserted_id(self):
|
||||
"""The inserted document's _id."""
|
||||
return self.__inserted_id
|
||||
|
||||
@property
|
||||
def acknowledged(self):
|
||||
"""Is this the result of an acknowledged write operation?"""
|
||||
return self.__acknowledged
|
||||
|
||||
|
||||
class ReturnDocument(object):
|
||||
"""An enum used with :meth:`Collection.find_one_and_replace` and
|
||||
:meth:`Collection.find_one_and_update`.
|
||||
"""
|
||||
Before = False
|
||||
"""Return the original document before it was updated/replaced, or
|
||||
``None`` if no document matches the query.
|
||||
"""
|
||||
After = True
|
||||
"""Return the updated/replaced or inserted document."""
|
||||
|
||||
|
||||
def _gen_index_name(keys):
|
||||
"""Generate an index name from the set of fields it is over.
|
||||
"""
|
||||
@ -321,11 +288,11 @@ class Collection(common.BaseObject):
|
||||
the :meth:`initialize_ordered_bulk_op` and
|
||||
:meth:`initialize_unordered_bulk_op` methods. Write operations are
|
||||
passed as a list using the write operation classes from the
|
||||
:mod:`~pymongo.bulk` module::
|
||||
:mod:`~pymongo.options` module::
|
||||
|
||||
>>> # DeleteOne, UpdateOne, and UpdateMany are also available.
|
||||
...
|
||||
>>> from pymongo.bulk import InsertOne, DeleteMany, ReplaceOne
|
||||
>>> from pymongo.options import InsertOne, DeleteMany, ReplaceOne
|
||||
>>> requests = [InsertOne({'foo': 1}), DeleteMany({'bar': 2}),
|
||||
... ReplaceOne({'bar': 1}, {'bim': 2}, upsert=True)]
|
||||
>>> coll.bulk_write(requests)
|
||||
@ -339,7 +306,7 @@ class Collection(common.BaseObject):
|
||||
parallel, and all operations will be attempted.
|
||||
|
||||
:Returns:
|
||||
An instance of :class:`~pymongo.bulk.BulkWriteResult`.
|
||||
An instance of :class:`~pymongo.results.BulkWriteResult`.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
"""
|
||||
@ -519,7 +486,7 @@ class Collection(common.BaseObject):
|
||||
added automatically.
|
||||
|
||||
:Returns:
|
||||
- An instance of :class:`InsertOneResult`.
|
||||
- An instance of :class:`~pymongo.results.InsertOneResult`.
|
||||
"""
|
||||
if not isinstance(document, collections.MutableMapping):
|
||||
raise TypeError("document must be a mutable mapping type")
|
||||
@ -1909,10 +1876,12 @@ class Collection(common.BaseObject):
|
||||
match the query, they are sorted and the first is replaced.
|
||||
- `upsert` (optional): When ``True``, inserts a new document if no
|
||||
document matches the query. Defaults to ``False``.
|
||||
- `return_document`: If :attr:`ReturnDocument.Before` (the default),
|
||||
- `return_document`: If
|
||||
:attr:`~pymongo.options.ReturnDocument.Before` (the default),
|
||||
returns the original document before it was replaced, or ``None``
|
||||
if no document matches. If :attr:`ReturnDocument.After`, returns
|
||||
the replaced or inserted document.
|
||||
if no document matches. If
|
||||
:attr:`~pymongo.options.ReturnDocument.After`, returns the replaced
|
||||
or inserted document.
|
||||
- `**kwargs` (optional): additional command arguments can be passed
|
||||
as keyword arguments (for example maxTimeMS can be used with
|
||||
recent server versions).
|
||||
@ -1947,10 +1916,12 @@ class Collection(common.BaseObject):
|
||||
match the query, they are sorted and the first is updated.
|
||||
- `upsert` (optional): When ``True``, inserts a new document if no
|
||||
document matches the query. Defaults to ``False``.
|
||||
- `return_document`: If :attr:`ReturnDocument.Before` (the default),
|
||||
- `return_document`: If
|
||||
:attr:`~pymongo.options.ReturnDocument.Before` (the default),
|
||||
returns the original document before it was updated, or ``None``
|
||||
if no document matches. If :attr:`ReturnDocument.After`, returns
|
||||
the updated or inserted document.
|
||||
if no document matches. If
|
||||
:attr:`~pymongo.options.ReturnDocument.After`, returns the updated
|
||||
or inserted document.
|
||||
- `**kwargs` (optional): additional command arguments can be passed
|
||||
as keyword arguments (for example maxTimeMS can be used with
|
||||
recent server versions).
|
||||
|
||||
188
pymongo/options.py
Normal file
188
pymongo/options.py
Normal file
@ -0,0 +1,188 @@
|
||||
# Copyright 2015 MongoDB, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Option class definitions."""
|
||||
|
||||
import collections
|
||||
|
||||
|
||||
class ReturnDocument(object):
|
||||
"""An enum used with
|
||||
:meth:`~pymongo.collection.Collection.find_one_and_replace` and
|
||||
:meth:`~pymongo.collection.Collection.find_one_and_update`.
|
||||
"""
|
||||
Before = False
|
||||
"""Return the original document before it was updated/replaced, or
|
||||
``None`` if no document matches the query.
|
||||
"""
|
||||
After = True
|
||||
"""Return the updated/replaced or inserted document."""
|
||||
|
||||
|
||||
class _WriteOp(object):
|
||||
"""Private base class for all write operations."""
|
||||
|
||||
__slots__ = ("_filter", "_doc", "_upsert")
|
||||
|
||||
def __init__(self, filter=None, doc=None, upsert=None):
|
||||
if filter is not None and not isinstance(filter, collections.Mapping):
|
||||
raise TypeError("filter must be a mapping type.")
|
||||
if upsert is not None and not isinstance(upsert, bool):
|
||||
raise TypeError("upsert must be True or False")
|
||||
self._filter = filter
|
||||
self._doc = doc
|
||||
self._upsert = upsert
|
||||
|
||||
|
||||
class InsertOne(_WriteOp):
|
||||
"""Represents an insert_one operation."""
|
||||
|
||||
def __init__(self, document):
|
||||
"""Create an InsertOne instance.
|
||||
|
||||
For use with :meth:`~pymongo.collection.Collection.bulk_write`.
|
||||
|
||||
:Parameters:
|
||||
- `document`: The document to insert. If the document is missing an
|
||||
_id field one will be added.
|
||||
"""
|
||||
super(InsertOne, self).__init__(doc=document)
|
||||
|
||||
def _add_to_bulk(self, bulkobj):
|
||||
"""Add this operation to the _Bulk instance `bulkobj`."""
|
||||
bulkobj.add_insert(self._doc)
|
||||
|
||||
def __repr__(self):
|
||||
return "InsertOne(%r)" % (self._doc,)
|
||||
|
||||
|
||||
class DeleteOne(_WriteOp):
|
||||
"""Represents a delete_one operation."""
|
||||
|
||||
def __init__(self, filter):
|
||||
"""Create a DeleteOne instance.
|
||||
|
||||
For use with :meth:`~pymongo.collection.Collection.bulk_write`.
|
||||
|
||||
:Parameters:
|
||||
- `filter`: A query that matches the document to delete.
|
||||
"""
|
||||
super(DeleteOne, self).__init__(filter)
|
||||
|
||||
def _add_to_bulk(self, bulkobj):
|
||||
"""Add this operation to the _Bulk instance `bulkobj`."""
|
||||
bulkobj.add_delete(self._filter, 1)
|
||||
|
||||
def __repr__(self):
|
||||
return "DeleteOne(%r)" % (self._filter,)
|
||||
|
||||
|
||||
class DeleteMany(_WriteOp):
|
||||
"""Represents a delete_many operation."""
|
||||
|
||||
def __init__(self, filter):
|
||||
"""Create a DeleteMany instance.
|
||||
|
||||
For use with :meth:`~pymongo.collection.Collection.bulk_write`.
|
||||
|
||||
:Parameters:
|
||||
- `filter`: A query that matches the documents to delete.
|
||||
"""
|
||||
super(DeleteMany, self).__init__(filter)
|
||||
|
||||
def _add_to_bulk(self, bulkobj):
|
||||
"""Add this operation to the _Bulk instance `bulkobj`."""
|
||||
bulkobj.add_delete(self._filter, 0)
|
||||
|
||||
def __repr__(self):
|
||||
return "DeleteMany(%r)" % (self._filter,)
|
||||
|
||||
|
||||
class ReplaceOne(_WriteOp):
|
||||
"""Represents a replace_one operation."""
|
||||
|
||||
def __init__(self, filter, replacement, upsert=False):
|
||||
"""Create a ReplaceOne instance.
|
||||
|
||||
For use with :meth:`~pymongo.collection.Collection.bulk_write`.
|
||||
|
||||
:Parameters:
|
||||
- `filter`: A query that matches the document to replace.
|
||||
- `replacement`: The new document.
|
||||
- `upsert` (optional): If ``True``, perform an insert if no documents
|
||||
match the filter.
|
||||
"""
|
||||
super(ReplaceOne, self).__init__(filter, replacement, upsert)
|
||||
|
||||
def _add_to_bulk(self, bulkobj):
|
||||
"""Add this operation to the _Bulk instance `bulkobj`."""
|
||||
bulkobj.add_replace(self._filter, self._doc, self._upsert)
|
||||
|
||||
def __repr__(self):
|
||||
return "ReplaceOne(%r, %r, %r)" % (self._filter,
|
||||
self._doc,
|
||||
self._upsert)
|
||||
|
||||
|
||||
class UpdateOne(_WriteOp):
|
||||
"""Represents an update_one operation."""
|
||||
|
||||
def __init__(self, filter, update, upsert=False):
|
||||
"""Represents an update_one operation.
|
||||
|
||||
For use with :meth:`~pymongo.collection.Collection.bulk_write`.
|
||||
|
||||
:Parameters:
|
||||
- `filter`: A query that matches the document to update.
|
||||
- `update`: The modifications to apply.
|
||||
- `upsert` (optional): If ``True``, perform an insert if no documents
|
||||
match the filter.
|
||||
"""
|
||||
super(UpdateOne, self).__init__(filter, update, upsert)
|
||||
|
||||
def _add_to_bulk(self, bulkobj):
|
||||
"""Add this operation to the _Bulk instance `bulkobj`."""
|
||||
bulkobj.add_update(self._filter, self._doc, False, self._upsert)
|
||||
|
||||
def __repr__(self):
|
||||
return "UpdateOne(%r, %r, %r)" % (self._filter,
|
||||
self._doc,
|
||||
self._upsert)
|
||||
|
||||
|
||||
class UpdateMany(_WriteOp):
|
||||
"""Represents an update_many operation."""
|
||||
|
||||
def __init__(self, filter, update, upsert=False):
|
||||
"""Create an UpdateMany instance.
|
||||
|
||||
For use with :meth:`~pymongo.collection.Collection.bulk_write`.
|
||||
|
||||
:Parameters:
|
||||
- `filter`: A query that matches the documents to update.
|
||||
- `update`: The modifications to apply.
|
||||
- `upsert` (optional): If ``True``, perform an insert if no documents
|
||||
match the filter.
|
||||
"""
|
||||
super(UpdateMany, self).__init__(filter, update, upsert)
|
||||
|
||||
def _add_to_bulk(self, bulkobj):
|
||||
"""Add this operation to the _Bulk instance `bulkobj`."""
|
||||
bulkobj.add_update(self._filter, self._doc, True, self._upsert)
|
||||
|
||||
def __repr__(self):
|
||||
return "UpdateMany(%r, %r, %r)" % (self._filter,
|
||||
self._doc,
|
||||
self._upsert)
|
||||
|
||||
117
pymongo/results.py
Normal file
117
pymongo/results.py
Normal file
@ -0,0 +1,117 @@
|
||||
# Copyright 2015 MongoDB, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Result class definitions."""
|
||||
|
||||
from pymongo.errors import InvalidOperation
|
||||
|
||||
|
||||
class InsertOneResult(object):
|
||||
"""The return type for :meth:`Collection.insert_one`."""
|
||||
|
||||
__slots__ = ("__inserted_id", "__acknowledged")
|
||||
|
||||
def __init__(self, inserted_id, acknowledged):
|
||||
self.__inserted_id = inserted_id
|
||||
self.__acknowledged = acknowledged
|
||||
|
||||
@property
|
||||
def inserted_id(self):
|
||||
"""The inserted document's _id."""
|
||||
return self.__inserted_id
|
||||
|
||||
@property
|
||||
def acknowledged(self):
|
||||
"""Is this the result of an acknowledged write operation?"""
|
||||
return self.__acknowledged
|
||||
|
||||
|
||||
class BulkWriteResult(object):
|
||||
"""An object wrapper for bulk API write results."""
|
||||
|
||||
__slots__ = ("__bulk_api_result", "__acknowledged")
|
||||
|
||||
def __init__(self, bulk_api_result, acknowledged):
|
||||
"""Create a BulkWriteResult instance.
|
||||
|
||||
:Parameters:
|
||||
- `bulk_api_result`: A result dict from the bulk API
|
||||
- `acknowledged`: Was this write result acknowledged? If ``False``
|
||||
then all properties of this object will raise
|
||||
:exc:`~pymongo.errors.InvalidOperation`.
|
||||
"""
|
||||
self.__bulk_api_result = bulk_api_result
|
||||
self.__acknowledged = acknowledged
|
||||
|
||||
def __raise_if_unacknowledged(self, property_name):
|
||||
"""Raise an exception on property access if unacknowledged."""
|
||||
if not self.__acknowledged:
|
||||
raise InvalidOperation("A value for %s is not available when "
|
||||
"the write is unacknowledged. Check the "
|
||||
"acknowledged attribute to avoid this "
|
||||
"error." % (property_name,))
|
||||
|
||||
@property
|
||||
def bulk_api_result(self):
|
||||
"""The raw bulk API result."""
|
||||
return self.__bulk_api_result
|
||||
|
||||
@property
|
||||
def acknowledged(self):
|
||||
"""Is this the result of an acknowledged bulk write operation?"""
|
||||
return self.__acknowledged
|
||||
|
||||
@property
|
||||
def inserted_count(self):
|
||||
"""The number of documents inserted."""
|
||||
self.__raise_if_unacknowledged("inserted_count")
|
||||
return self.__bulk_api_result.get("nInserted")
|
||||
|
||||
@property
|
||||
def matched_count(self):
|
||||
"""The number of documents matched for an update."""
|
||||
self.__raise_if_unacknowledged("matched_count")
|
||||
return self.__bulk_api_result.get("nMatched")
|
||||
|
||||
@property
|
||||
def modified_count(self):
|
||||
"""The number of documents modified.
|
||||
|
||||
.. note:: modified_count is only reported by MongoDB 2.6 and later.
|
||||
When connected to an earlier server version, or in certain mixed
|
||||
version sharding configurations, this attribute will be set to
|
||||
``None``.
|
||||
"""
|
||||
self.__raise_if_unacknowledged("modified_count")
|
||||
return self.__bulk_api_result.get("nModified")
|
||||
|
||||
@property
|
||||
def deleted_count(self):
|
||||
"""The number of documents deleted."""
|
||||
self.__raise_if_unacknowledged("deleted_count")
|
||||
return self.__bulk_api_result.get("nRemoved")
|
||||
|
||||
@property
|
||||
def upserted_count(self):
|
||||
"""The number of documents upserted."""
|
||||
self.__raise_if_unacknowledged("upserted_count")
|
||||
return self.__bulk_api_result.get("nUpserted")
|
||||
|
||||
@property
|
||||
def upserted_ids(self):
|
||||
"""A map of operation index to the _id of the upserted document."""
|
||||
self.__raise_if_unacknowledged("upserted_ids")
|
||||
if self.__bulk_api_result:
|
||||
return dict((upsert["index"], upsert["_id"])
|
||||
for upsert in self.bulk_api_result["upserted"])
|
||||
@ -22,7 +22,7 @@ from bson import InvalidDocument, SON
|
||||
from bson.objectid import ObjectId
|
||||
from bson.py3compat import string_type
|
||||
from pymongo import MongoClient
|
||||
from pymongo.bulk import *
|
||||
from pymongo.options import *
|
||||
from pymongo.common import partition_node
|
||||
from pymongo.errors import BulkWriteError, InvalidOperation, OperationFailure
|
||||
from pymongo.write_concern import WriteConcern
|
||||
|
||||
@ -35,7 +35,7 @@ from bson.son import SON
|
||||
from pymongo import (ASCENDING, DESCENDING, GEO2D,
|
||||
GEOHAYSTACK, GEOSPHERE, HASHED, TEXT)
|
||||
from pymongo import MongoClient
|
||||
from pymongo.collection import Collection, ReturnDocument, InsertOneResult
|
||||
from pymongo.collection import Collection
|
||||
from pymongo.command_cursor import CommandCursor
|
||||
from pymongo.cursor import EXHAUST
|
||||
from pymongo.errors import (ConfigurationError,
|
||||
@ -46,7 +46,9 @@ from pymongo.errors import (ConfigurationError,
|
||||
InvalidOperation,
|
||||
OperationFailure,
|
||||
WTimeoutError)
|
||||
from pymongo.options import ReturnDocument
|
||||
from pymongo.read_preferences import ReadPreference
|
||||
from pymongo.results import InsertOneResult
|
||||
from pymongo.son_manipulator import SONManipulator
|
||||
from pymongo.write_concern import WriteConcern
|
||||
from test.test_client import IntegrationTest
|
||||
|
||||
Loading…
Reference in New Issue
Block a user