results.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. # Copyright 2015 MongoDB, Inc.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. """Result class definitions."""
  15. from pymongo.errors import InvalidOperation
  16. class _WriteResult(object):
  17. """Base class for write result classes."""
  18. def __init__(self, acknowledged):
  19. self.__acknowledged = acknowledged
  20. def _raise_if_unacknowledged(self, property_name):
  21. """Raise an exception on property access if unacknowledged."""
  22. if not self.__acknowledged:
  23. raise InvalidOperation("A value for %s is not available when "
  24. "the write is unacknowledged. Check the "
  25. "acknowledged attribute to avoid this "
  26. "error." % (property_name,))
  27. @property
  28. def acknowledged(self):
  29. """Is this the result of an acknowledged write operation?
  30. The :attr:`acknowledged` attribute will be ``False`` when using
  31. ``WriteConcern(w=0)``, otherwise ``True``.
  32. .. note::
  33. If the :attr:`acknowledged` attribute is ``False`` all other
  34. attibutes of this class will raise
  35. :class:`~pymongo.errors.InvalidOperation` when accessed. Values for
  36. other attributes cannot be determined if the write operation was
  37. unacknowledged.
  38. .. seealso::
  39. :class:`~pymongo.write_concern.WriteConcern`
  40. """
  41. return self.__acknowledged
  42. class InsertOneResult(_WriteResult):
  43. """The return type for :meth:`~pymongo.collection.Collection.insert_one`.
  44. """
  45. __slots__ = ("__inserted_id", "__acknowledged")
  46. def __init__(self, inserted_id, acknowledged):
  47. self.__inserted_id = inserted_id
  48. super(InsertOneResult, self).__init__(acknowledged)
  49. @property
  50. def inserted_id(self):
  51. """The inserted document's _id."""
  52. return self.__inserted_id
  53. class InsertManyResult(_WriteResult):
  54. """The return type for :meth:`~pymongo.collection.Collection.insert_many`.
  55. """
  56. __slots__ = ("__inserted_ids", "__acknowledged")
  57. def __init__(self, inserted_ids, acknowledged):
  58. self.__inserted_ids = inserted_ids
  59. super(InsertManyResult, self).__init__(acknowledged)
  60. @property
  61. def inserted_ids(self):
  62. """A list of _ids of the inserted documents, in the order provided.
  63. .. note:: If ``False`` is passed for the `ordered` parameter to
  64. :meth:`~pymongo.collection.Collection.insert_many` the server
  65. may have inserted the documents in a different order than what
  66. is presented here.
  67. """
  68. return self.__inserted_ids
  69. class UpdateResult(_WriteResult):
  70. """The return type for :meth:`~pymongo.collection.Collection.update_one`,
  71. :meth:`~pymongo.collection.Collection.update_many`, and
  72. :meth:`~pymongo.collection.Collection.replace_one`.
  73. """
  74. __slots__ = ("__raw_result", "__acknowledged")
  75. def __init__(self, raw_result, acknowledged):
  76. self.__raw_result = raw_result
  77. super(UpdateResult, self).__init__(acknowledged)
  78. @property
  79. def raw_result(self):
  80. """The raw result document returned by the server."""
  81. return self.__raw_result
  82. @property
  83. def matched_count(self):
  84. """The number of documents matched for this update."""
  85. self._raise_if_unacknowledged("matched_count")
  86. if self.upserted_id is not None:
  87. return 0
  88. return self.__raw_result.get("n", 0)
  89. @property
  90. def modified_count(self):
  91. """The number of documents modified.
  92. .. note:: modified_count is only reported by MongoDB 2.6 and later.
  93. When connected to an earlier server version, or in certain mixed
  94. version sharding configurations, this attribute will be set to
  95. ``None``.
  96. """
  97. self._raise_if_unacknowledged("modified_count")
  98. return self.__raw_result.get("nModified")
  99. @property
  100. def upserted_id(self):
  101. """The _id of the inserted document if an upsert took place. Otherwise
  102. ``None``.
  103. """
  104. self._raise_if_unacknowledged("upserted_id")
  105. return self.__raw_result.get("upserted")
  106. class DeleteResult(_WriteResult):
  107. """The return type for :meth:`~pymongo.collection.Collection.delete_one`
  108. and :meth:`~pymongo.collection.Collection.delete_many`"""
  109. __slots__ = ("__raw_result", "__acknowledged")
  110. def __init__(self, raw_result, acknowledged):
  111. self.__raw_result = raw_result
  112. super(DeleteResult, self).__init__(acknowledged)
  113. @property
  114. def raw_result(self):
  115. """The raw result document returned by the server."""
  116. return self.__raw_result
  117. @property
  118. def deleted_count(self):
  119. """The number of documents deleted."""
  120. self._raise_if_unacknowledged("deleted_count")
  121. return self.__raw_result.get("n", 0)
  122. class BulkWriteResult(_WriteResult):
  123. """An object wrapper for bulk API write results."""
  124. __slots__ = ("__bulk_api_result", "__acknowledged")
  125. def __init__(self, bulk_api_result, acknowledged):
  126. """Create a BulkWriteResult instance.
  127. :Parameters:
  128. - `bulk_api_result`: A result dict from the bulk API
  129. - `acknowledged`: Was this write result acknowledged? If ``False``
  130. then all properties of this object will raise
  131. :exc:`~pymongo.errors.InvalidOperation`.
  132. """
  133. self.__bulk_api_result = bulk_api_result
  134. super(BulkWriteResult, self).__init__(acknowledged)
  135. @property
  136. def bulk_api_result(self):
  137. """The raw bulk API result."""
  138. return self.__bulk_api_result
  139. @property
  140. def inserted_count(self):
  141. """The number of documents inserted."""
  142. self._raise_if_unacknowledged("inserted_count")
  143. return self.__bulk_api_result.get("nInserted")
  144. @property
  145. def matched_count(self):
  146. """The number of documents matched for an update."""
  147. self._raise_if_unacknowledged("matched_count")
  148. return self.__bulk_api_result.get("nMatched")
  149. @property
  150. def modified_count(self):
  151. """The number of documents modified.
  152. .. note:: modified_count is only reported by MongoDB 2.6 and later.
  153. When connected to an earlier server version, or in certain mixed
  154. version sharding configurations, this attribute will be set to
  155. ``None``.
  156. """
  157. self._raise_if_unacknowledged("modified_count")
  158. return self.__bulk_api_result.get("nModified")
  159. @property
  160. def deleted_count(self):
  161. """The number of documents deleted."""
  162. self._raise_if_unacknowledged("deleted_count")
  163. return self.__bulk_api_result.get("nRemoved")
  164. @property
  165. def upserted_count(self):
  166. """The number of documents upserted."""
  167. self._raise_if_unacknowledged("upserted_count")
  168. return self.__bulk_api_result.get("nUpserted")
  169. @property
  170. def upserted_ids(self):
  171. """A map of operation index to the _id of the upserted document."""
  172. self._raise_if_unacknowledged("upserted_ids")
  173. if self.__bulk_api_result:
  174. return dict((upsert["index"], upsert["_id"])
  175. for upsert in self.bulk_api_result["upserted"])