sensu-plugins-mongodb-mrtrotl 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1 -0
  3. data/LICENSE +22 -0
  4. data/README.md +27 -0
  5. data/bin/check-mongodb-metric.rb +144 -0
  6. data/bin/check-mongodb-query-count.rb +267 -0
  7. data/bin/check-mongodb.py +1644 -0
  8. data/bin/check-mongodb.rb +5 -0
  9. data/bin/metrics-mongodb-replication.rb +254 -0
  10. data/bin/metrics-mongodb.rb +133 -0
  11. data/lib/bson/__init__.py +1347 -0
  12. data/lib/bson/__pycache__/__init__.cpython-310.pyc +0 -0
  13. data/lib/bson/__pycache__/_helpers.cpython-310.pyc +0 -0
  14. data/lib/bson/__pycache__/binary.cpython-310.pyc +0 -0
  15. data/lib/bson/__pycache__/code.cpython-310.pyc +0 -0
  16. data/lib/bson/__pycache__/codec_options.cpython-310.pyc +0 -0
  17. data/lib/bson/__pycache__/dbref.cpython-310.pyc +0 -0
  18. data/lib/bson/__pycache__/decimal128.cpython-310.pyc +0 -0
  19. data/lib/bson/__pycache__/errors.cpython-310.pyc +0 -0
  20. data/lib/bson/__pycache__/int64.cpython-310.pyc +0 -0
  21. data/lib/bson/__pycache__/json_util.cpython-310.pyc +0 -0
  22. data/lib/bson/__pycache__/max_key.cpython-310.pyc +0 -0
  23. data/lib/bson/__pycache__/min_key.cpython-310.pyc +0 -0
  24. data/lib/bson/__pycache__/objectid.cpython-310.pyc +0 -0
  25. data/lib/bson/__pycache__/raw_bson.cpython-310.pyc +0 -0
  26. data/lib/bson/__pycache__/regex.cpython-310.pyc +0 -0
  27. data/lib/bson/__pycache__/son.cpython-310.pyc +0 -0
  28. data/lib/bson/__pycache__/timestamp.cpython-310.pyc +0 -0
  29. data/lib/bson/__pycache__/tz_util.cpython-310.pyc +0 -0
  30. data/lib/bson/_cbson.cpython-310-x86_64-linux-gnu.so +0 -0
  31. data/lib/bson/_helpers.py +41 -0
  32. data/lib/bson/binary.py +364 -0
  33. data/lib/bson/code.py +101 -0
  34. data/lib/bson/codec_options.py +414 -0
  35. data/lib/bson/codec_options.pyi +100 -0
  36. data/lib/bson/dbref.py +133 -0
  37. data/lib/bson/decimal128.py +314 -0
  38. data/lib/bson/errors.py +35 -0
  39. data/lib/bson/int64.py +39 -0
  40. data/lib/bson/json_util.py +874 -0
  41. data/lib/bson/max_key.py +55 -0
  42. data/lib/bson/min_key.py +55 -0
  43. data/lib/bson/objectid.py +286 -0
  44. data/lib/bson/py.typed +2 -0
  45. data/lib/bson/raw_bson.py +175 -0
  46. data/lib/bson/regex.py +135 -0
  47. data/lib/bson/son.py +208 -0
  48. data/lib/bson/timestamp.py +124 -0
  49. data/lib/bson/tz_util.py +52 -0
  50. data/lib/gridfs/__init__.py +1015 -0
  51. data/lib/gridfs/__pycache__/__init__.cpython-310.pyc +0 -0
  52. data/lib/gridfs/__pycache__/errors.cpython-310.pyc +0 -0
  53. data/lib/gridfs/__pycache__/grid_file.cpython-310.pyc +0 -0
  54. data/lib/gridfs/errors.py +33 -0
  55. data/lib/gridfs/grid_file.py +907 -0
  56. data/lib/gridfs/py.typed +2 -0
  57. data/lib/pymongo/__init__.py +185 -0
  58. data/lib/pymongo/__pycache__/__init__.cpython-310.pyc +0 -0
  59. data/lib/pymongo/__pycache__/_csot.cpython-310.pyc +0 -0
  60. data/lib/pymongo/__pycache__/aggregation.cpython-310.pyc +0 -0
  61. data/lib/pymongo/__pycache__/auth.cpython-310.pyc +0 -0
  62. data/lib/pymongo/__pycache__/auth_aws.cpython-310.pyc +0 -0
  63. data/lib/pymongo/__pycache__/bulk.cpython-310.pyc +0 -0
  64. data/lib/pymongo/__pycache__/change_stream.cpython-310.pyc +0 -0
  65. data/lib/pymongo/__pycache__/client_options.cpython-310.pyc +0 -0
  66. data/lib/pymongo/__pycache__/client_session.cpython-310.pyc +0 -0
  67. data/lib/pymongo/__pycache__/collation.cpython-310.pyc +0 -0
  68. data/lib/pymongo/__pycache__/collection.cpython-310.pyc +0 -0
  69. data/lib/pymongo/__pycache__/command_cursor.cpython-310.pyc +0 -0
  70. data/lib/pymongo/__pycache__/common.cpython-310.pyc +0 -0
  71. data/lib/pymongo/__pycache__/compression_support.cpython-310.pyc +0 -0
  72. data/lib/pymongo/__pycache__/cursor.cpython-310.pyc +0 -0
  73. data/lib/pymongo/__pycache__/daemon.cpython-310.pyc +0 -0
  74. data/lib/pymongo/__pycache__/database.cpython-310.pyc +0 -0
  75. data/lib/pymongo/__pycache__/driver_info.cpython-310.pyc +0 -0
  76. data/lib/pymongo/__pycache__/encryption.cpython-310.pyc +0 -0
  77. data/lib/pymongo/__pycache__/encryption_options.cpython-310.pyc +0 -0
  78. data/lib/pymongo/__pycache__/errors.cpython-310.pyc +0 -0
  79. data/lib/pymongo/__pycache__/event_loggers.cpython-310.pyc +0 -0
  80. data/lib/pymongo/__pycache__/hello.cpython-310.pyc +0 -0
  81. data/lib/pymongo/__pycache__/helpers.cpython-310.pyc +0 -0
  82. data/lib/pymongo/__pycache__/max_staleness_selectors.cpython-310.pyc +0 -0
  83. data/lib/pymongo/__pycache__/message.cpython-310.pyc +0 -0
  84. data/lib/pymongo/__pycache__/mongo_client.cpython-310.pyc +0 -0
  85. data/lib/pymongo/__pycache__/monitor.cpython-310.pyc +0 -0
  86. data/lib/pymongo/__pycache__/monitoring.cpython-310.pyc +0 -0
  87. data/lib/pymongo/__pycache__/network.cpython-310.pyc +0 -0
  88. data/lib/pymongo/__pycache__/ocsp_cache.cpython-310.pyc +0 -0
  89. data/lib/pymongo/__pycache__/ocsp_support.cpython-310.pyc +0 -0
  90. data/lib/pymongo/__pycache__/operations.cpython-310.pyc +0 -0
  91. data/lib/pymongo/__pycache__/periodic_executor.cpython-310.pyc +0 -0
  92. data/lib/pymongo/__pycache__/pool.cpython-310.pyc +0 -0
  93. data/lib/pymongo/__pycache__/pyopenssl_context.cpython-310.pyc +0 -0
  94. data/lib/pymongo/__pycache__/read_concern.cpython-310.pyc +0 -0
  95. data/lib/pymongo/__pycache__/read_preferences.cpython-310.pyc +0 -0
  96. data/lib/pymongo/__pycache__/response.cpython-310.pyc +0 -0
  97. data/lib/pymongo/__pycache__/results.cpython-310.pyc +0 -0
  98. data/lib/pymongo/__pycache__/saslprep.cpython-310.pyc +0 -0
  99. data/lib/pymongo/__pycache__/server.cpython-310.pyc +0 -0
  100. data/lib/pymongo/__pycache__/server_api.cpython-310.pyc +0 -0
  101. data/lib/pymongo/__pycache__/server_description.cpython-310.pyc +0 -0
  102. data/lib/pymongo/__pycache__/server_selectors.cpython-310.pyc +0 -0
  103. data/lib/pymongo/__pycache__/server_type.cpython-310.pyc +0 -0
  104. data/lib/pymongo/__pycache__/settings.cpython-310.pyc +0 -0
  105. data/lib/pymongo/__pycache__/socket_checker.cpython-310.pyc +0 -0
  106. data/lib/pymongo/__pycache__/srv_resolver.cpython-310.pyc +0 -0
  107. data/lib/pymongo/__pycache__/ssl_context.cpython-310.pyc +0 -0
  108. data/lib/pymongo/__pycache__/ssl_support.cpython-310.pyc +0 -0
  109. data/lib/pymongo/__pycache__/topology.cpython-310.pyc +0 -0
  110. data/lib/pymongo/__pycache__/topology_description.cpython-310.pyc +0 -0
  111. data/lib/pymongo/__pycache__/typings.cpython-310.pyc +0 -0
  112. data/lib/pymongo/__pycache__/uri_parser.cpython-310.pyc +0 -0
  113. data/lib/pymongo/__pycache__/write_concern.cpython-310.pyc +0 -0
  114. data/lib/pymongo/_cmessage.cpython-310-x86_64-linux-gnu.so +0 -0
  115. data/lib/pymongo/_csot.py +118 -0
  116. data/lib/pymongo/aggregation.py +229 -0
  117. data/lib/pymongo/auth.py +549 -0
  118. data/lib/pymongo/auth_aws.py +94 -0
  119. data/lib/pymongo/bulk.py +513 -0
  120. data/lib/pymongo/change_stream.py +457 -0
  121. data/lib/pymongo/client_options.py +302 -0
  122. data/lib/pymongo/client_session.py +1112 -0
  123. data/lib/pymongo/collation.py +224 -0
  124. data/lib/pymongo/collection.py +3204 -0
  125. data/lib/pymongo/command_cursor.py +353 -0
  126. data/lib/pymongo/common.py +984 -0
  127. data/lib/pymongo/compression_support.py +149 -0
  128. data/lib/pymongo/cursor.py +1345 -0
  129. data/lib/pymongo/daemon.py +141 -0
  130. data/lib/pymongo/database.py +1202 -0
  131. data/lib/pymongo/driver_info.py +42 -0
  132. data/lib/pymongo/encryption.py +884 -0
  133. data/lib/pymongo/encryption_options.py +221 -0
  134. data/lib/pymongo/errors.py +365 -0
  135. data/lib/pymongo/event_loggers.py +221 -0
  136. data/lib/pymongo/hello.py +219 -0
  137. data/lib/pymongo/helpers.py +259 -0
  138. data/lib/pymongo/max_staleness_selectors.py +114 -0
  139. data/lib/pymongo/message.py +1440 -0
  140. data/lib/pymongo/mongo_client.py +2144 -0
  141. data/lib/pymongo/monitor.py +440 -0
  142. data/lib/pymongo/monitoring.py +1801 -0
  143. data/lib/pymongo/network.py +311 -0
  144. data/lib/pymongo/ocsp_cache.py +87 -0
  145. data/lib/pymongo/ocsp_support.py +372 -0
  146. data/lib/pymongo/operations.py +507 -0
  147. data/lib/pymongo/periodic_executor.py +183 -0
  148. data/lib/pymongo/pool.py +1660 -0
  149. data/lib/pymongo/py.typed +2 -0
  150. data/lib/pymongo/pyopenssl_context.py +383 -0
  151. data/lib/pymongo/read_concern.py +75 -0
  152. data/lib/pymongo/read_preferences.py +609 -0
  153. data/lib/pymongo/response.py +109 -0
  154. data/lib/pymongo/results.py +217 -0
  155. data/lib/pymongo/saslprep.py +113 -0
  156. data/lib/pymongo/server.py +247 -0
  157. data/lib/pymongo/server_api.py +170 -0
  158. data/lib/pymongo/server_description.py +285 -0
  159. data/lib/pymongo/server_selectors.py +153 -0
  160. data/lib/pymongo/server_type.py +32 -0
  161. data/lib/pymongo/settings.py +159 -0
  162. data/lib/pymongo/socket_checker.py +104 -0
  163. data/lib/pymongo/srv_resolver.py +126 -0
  164. data/lib/pymongo/ssl_context.py +39 -0
  165. data/lib/pymongo/ssl_support.py +99 -0
  166. data/lib/pymongo/topology.py +890 -0
  167. data/lib/pymongo/topology_description.py +639 -0
  168. data/lib/pymongo/typings.py +39 -0
  169. data/lib/pymongo/uri_parser.py +624 -0
  170. data/lib/pymongo/write_concern.py +129 -0
  171. data/lib/pymongo-4.2.0.dist-info/INSTALLER +1 -0
  172. data/lib/pymongo-4.2.0.dist-info/LICENSE +201 -0
  173. data/lib/pymongo-4.2.0.dist-info/METADATA +250 -0
  174. data/lib/pymongo-4.2.0.dist-info/RECORD +167 -0
  175. data/lib/pymongo-4.2.0.dist-info/REQUESTED +0 -0
  176. data/lib/pymongo-4.2.0.dist-info/WHEEL +6 -0
  177. data/lib/pymongo-4.2.0.dist-info/top_level.txt +3 -0
  178. data/lib/sensu-plugins-mongodb/metrics.rb +391 -0
  179. data/lib/sensu-plugins-mongodb/version.rb +9 -0
  180. data/lib/sensu-plugins-mongodb.rb +1 -0
  181. metadata +407 -0
@@ -0,0 +1,1202 @@
1
+ # Copyright 2009-present 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
+
15
+ """Database level operations."""
16
+ from typing import (
17
+ TYPE_CHECKING,
18
+ Any,
19
+ Dict,
20
+ Generic,
21
+ List,
22
+ Mapping,
23
+ MutableMapping,
24
+ NoReturn,
25
+ Optional,
26
+ Sequence,
27
+ TypeVar,
28
+ Union,
29
+ cast,
30
+ )
31
+
32
+ from bson.codec_options import DEFAULT_CODEC_OPTIONS, CodecOptions
33
+ from bson.dbref import DBRef
34
+ from bson.son import SON
35
+ from bson.timestamp import Timestamp
36
+ from pymongo import _csot, common
37
+ from pymongo.aggregation import _DatabaseAggregationCommand
38
+ from pymongo.change_stream import DatabaseChangeStream
39
+ from pymongo.collection import Collection
40
+ from pymongo.command_cursor import CommandCursor
41
+ from pymongo.common import _ecc_coll_name, _ecoc_coll_name, _esc_coll_name
42
+ from pymongo.errors import CollectionInvalid, InvalidName
43
+ from pymongo.read_preferences import ReadPreference, _ServerMode
44
+ from pymongo.typings import _CollationIn, _DocumentType, _Pipeline
45
+
46
+
47
+ def _check_name(name):
48
+ """Check if a database name is valid."""
49
+ if not name:
50
+ raise InvalidName("database name cannot be the empty string")
51
+
52
+ for invalid_char in [" ", ".", "$", "/", "\\", "\x00", '"']:
53
+ if invalid_char in name:
54
+ raise InvalidName("database names cannot contain the character %r" % invalid_char)
55
+
56
+
57
+ if TYPE_CHECKING:
58
+ import bson.codec_options
59
+ from pymongo.client_session import ClientSession
60
+ from pymongo.mongo_client import MongoClient
61
+ from pymongo.read_concern import ReadConcern
62
+ from pymongo.write_concern import WriteConcern
63
+
64
+
65
+ _CodecDocumentType = TypeVar("_CodecDocumentType", bound=Mapping[str, Any])
66
+
67
+
68
+ class Database(common.BaseObject, Generic[_DocumentType]):
69
+ """A Mongo database."""
70
+
71
+ def __init__(
72
+ self,
73
+ client: "MongoClient[_DocumentType]",
74
+ name: str,
75
+ codec_options: Optional[CodecOptions] = None,
76
+ read_preference: Optional[_ServerMode] = None,
77
+ write_concern: Optional["WriteConcern"] = None,
78
+ read_concern: Optional["ReadConcern"] = None,
79
+ ) -> None:
80
+ """Get a database by client and name.
81
+
82
+ Raises :class:`TypeError` if `name` is not an instance of
83
+ :class:`basestring` (:class:`str` in python 3). Raises
84
+ :class:`~pymongo.errors.InvalidName` if `name` is not a valid
85
+ database name.
86
+
87
+ :Parameters:
88
+ - `client`: A :class:`~pymongo.mongo_client.MongoClient` instance.
89
+ - `name`: The database name.
90
+ - `codec_options` (optional): An instance of
91
+ :class:`~bson.codec_options.CodecOptions`. If ``None`` (the
92
+ default) client.codec_options is used.
93
+ - `read_preference` (optional): The read preference to use. If
94
+ ``None`` (the default) client.read_preference is used.
95
+ - `write_concern` (optional): An instance of
96
+ :class:`~pymongo.write_concern.WriteConcern`. If ``None`` (the
97
+ default) client.write_concern is used.
98
+ - `read_concern` (optional): An instance of
99
+ :class:`~pymongo.read_concern.ReadConcern`. If ``None`` (the
100
+ default) client.read_concern is used.
101
+
102
+ .. seealso:: The MongoDB documentation on `databases <https://dochub.mongodb.org/core/databases>`_.
103
+
104
+ .. versionchanged:: 4.0
105
+ Removed the eval, system_js, error, last_status, previous_error,
106
+ reset_error_history, authenticate, logout, collection_names,
107
+ current_op, add_user, remove_user, profiling_level,
108
+ set_profiling_level, and profiling_info methods.
109
+ See the :ref:`pymongo4-migration-guide`.
110
+
111
+ .. versionchanged:: 3.2
112
+ Added the read_concern option.
113
+
114
+ .. versionchanged:: 3.0
115
+ Added the codec_options, read_preference, and write_concern options.
116
+ :class:`~pymongo.database.Database` no longer returns an instance
117
+ of :class:`~pymongo.collection.Collection` for attribute names
118
+ with leading underscores. You must use dict-style lookups instead::
119
+
120
+ db['__my_collection__']
121
+
122
+ Not:
123
+
124
+ db.__my_collection__
125
+ """
126
+ super(Database, self).__init__(
127
+ codec_options or client.codec_options,
128
+ read_preference or client.read_preference,
129
+ write_concern or client.write_concern,
130
+ read_concern or client.read_concern,
131
+ )
132
+
133
+ if not isinstance(name, str):
134
+ raise TypeError("name must be an instance of str")
135
+
136
+ if name != "$external":
137
+ _check_name(name)
138
+
139
+ self.__name = name
140
+ self.__client: MongoClient[_DocumentType] = client
141
+ self._timeout = client.options.timeout
142
+
143
+ @property
144
+ def client(self) -> "MongoClient[_DocumentType]":
145
+ """The client instance for this :class:`Database`."""
146
+ return self.__client
147
+
148
+ @property
149
+ def name(self) -> str:
150
+ """The name of this :class:`Database`."""
151
+ return self.__name
152
+
153
+ def with_options(
154
+ self,
155
+ codec_options: Optional[CodecOptions] = None,
156
+ read_preference: Optional[_ServerMode] = None,
157
+ write_concern: Optional["WriteConcern"] = None,
158
+ read_concern: Optional["ReadConcern"] = None,
159
+ ) -> "Database[_DocumentType]":
160
+ """Get a clone of this database changing the specified settings.
161
+
162
+ >>> db1.read_preference
163
+ Primary()
164
+ >>> from pymongo import ReadPreference
165
+ >>> db2 = db1.with_options(read_preference=ReadPreference.SECONDARY)
166
+ >>> db1.read_preference
167
+ Primary()
168
+ >>> db2.read_preference
169
+ Secondary(tag_sets=None)
170
+
171
+ :Parameters:
172
+ - `codec_options` (optional): An instance of
173
+ :class:`~bson.codec_options.CodecOptions`. If ``None`` (the
174
+ default) the :attr:`codec_options` of this :class:`Collection`
175
+ is used.
176
+ - `read_preference` (optional): The read preference to use. If
177
+ ``None`` (the default) the :attr:`read_preference` of this
178
+ :class:`Collection` is used. See :mod:`~pymongo.read_preferences`
179
+ for options.
180
+ - `write_concern` (optional): An instance of
181
+ :class:`~pymongo.write_concern.WriteConcern`. If ``None`` (the
182
+ default) the :attr:`write_concern` of this :class:`Collection`
183
+ is used.
184
+ - `read_concern` (optional): An instance of
185
+ :class:`~pymongo.read_concern.ReadConcern`. If ``None`` (the
186
+ default) the :attr:`read_concern` of this :class:`Collection`
187
+ is used.
188
+
189
+ .. versionadded:: 3.8
190
+ """
191
+ return Database(
192
+ self.client,
193
+ self.__name,
194
+ codec_options or self.codec_options,
195
+ read_preference or self.read_preference,
196
+ write_concern or self.write_concern,
197
+ read_concern or self.read_concern,
198
+ )
199
+
200
+ def __eq__(self, other: Any) -> bool:
201
+ if isinstance(other, Database):
202
+ return self.__client == other.client and self.__name == other.name
203
+ return NotImplemented
204
+
205
+ def __ne__(self, other: Any) -> bool:
206
+ return not self == other
207
+
208
+ def __hash__(self) -> int:
209
+ return hash((self.__client, self.__name))
210
+
211
+ def __repr__(self):
212
+ return "Database(%r, %r)" % (self.__client, self.__name)
213
+
214
+ def __getattr__(self, name: str) -> Collection[_DocumentType]:
215
+ """Get a collection of this database by name.
216
+
217
+ Raises InvalidName if an invalid collection name is used.
218
+
219
+ :Parameters:
220
+ - `name`: the name of the collection to get
221
+ """
222
+ if name.startswith("_"):
223
+ raise AttributeError(
224
+ "Database has no attribute %r. To access the %s"
225
+ " collection, use database[%r]." % (name, name, name)
226
+ )
227
+ return self.__getitem__(name)
228
+
229
+ def __getitem__(self, name: str) -> "Collection[_DocumentType]":
230
+ """Get a collection of this database by name.
231
+
232
+ Raises InvalidName if an invalid collection name is used.
233
+
234
+ :Parameters:
235
+ - `name`: the name of the collection to get
236
+ """
237
+ return Collection(self, name)
238
+
239
+ def get_collection(
240
+ self,
241
+ name: str,
242
+ codec_options: Optional[CodecOptions] = None,
243
+ read_preference: Optional[_ServerMode] = None,
244
+ write_concern: Optional["WriteConcern"] = None,
245
+ read_concern: Optional["ReadConcern"] = None,
246
+ ) -> Collection[_DocumentType]:
247
+ """Get a :class:`~pymongo.collection.Collection` with the given name
248
+ and options.
249
+
250
+ Useful for creating a :class:`~pymongo.collection.Collection` with
251
+ different codec options, read preference, and/or write concern from
252
+ this :class:`Database`.
253
+
254
+ >>> db.read_preference
255
+ Primary()
256
+ >>> coll1 = db.test
257
+ >>> coll1.read_preference
258
+ Primary()
259
+ >>> from pymongo import ReadPreference
260
+ >>> coll2 = db.get_collection(
261
+ ... 'test', read_preference=ReadPreference.SECONDARY)
262
+ >>> coll2.read_preference
263
+ Secondary(tag_sets=None)
264
+
265
+ :Parameters:
266
+ - `name`: The name of the collection - a string.
267
+ - `codec_options` (optional): An instance of
268
+ :class:`~bson.codec_options.CodecOptions`. If ``None`` (the
269
+ default) the :attr:`codec_options` of this :class:`Database` is
270
+ used.
271
+ - `read_preference` (optional): The read preference to use. If
272
+ ``None`` (the default) the :attr:`read_preference` of this
273
+ :class:`Database` is used. See :mod:`~pymongo.read_preferences`
274
+ for options.
275
+ - `write_concern` (optional): An instance of
276
+ :class:`~pymongo.write_concern.WriteConcern`. If ``None`` (the
277
+ default) the :attr:`write_concern` of this :class:`Database` is
278
+ used.
279
+ - `read_concern` (optional): An instance of
280
+ :class:`~pymongo.read_concern.ReadConcern`. If ``None`` (the
281
+ default) the :attr:`read_concern` of this :class:`Database` is
282
+ used.
283
+ """
284
+ return Collection(
285
+ self,
286
+ name,
287
+ False,
288
+ codec_options,
289
+ read_preference,
290
+ write_concern,
291
+ read_concern,
292
+ )
293
+
294
+ @_csot.apply
295
+ def create_collection(
296
+ self,
297
+ name: str,
298
+ codec_options: Optional[CodecOptions] = None,
299
+ read_preference: Optional[_ServerMode] = None,
300
+ write_concern: Optional["WriteConcern"] = None,
301
+ read_concern: Optional["ReadConcern"] = None,
302
+ session: Optional["ClientSession"] = None,
303
+ check_exists: Optional[bool] = True,
304
+ **kwargs: Any,
305
+ ) -> Collection[_DocumentType]:
306
+ """Create a new :class:`~pymongo.collection.Collection` in this
307
+ database.
308
+
309
+ Normally collection creation is automatic. This method should
310
+ only be used to specify options on
311
+ creation. :class:`~pymongo.errors.CollectionInvalid` will be
312
+ raised if the collection already exists.
313
+
314
+ :Parameters:
315
+ - `name`: the name of the collection to create
316
+ - `codec_options` (optional): An instance of
317
+ :class:`~bson.codec_options.CodecOptions`. If ``None`` (the
318
+ default) the :attr:`codec_options` of this :class:`Database` is
319
+ used.
320
+ - `read_preference` (optional): The read preference to use. If
321
+ ``None`` (the default) the :attr:`read_preference` of this
322
+ :class:`Database` is used.
323
+ - `write_concern` (optional): An instance of
324
+ :class:`~pymongo.write_concern.WriteConcern`. If ``None`` (the
325
+ default) the :attr:`write_concern` of this :class:`Database` is
326
+ used.
327
+ - `read_concern` (optional): An instance of
328
+ :class:`~pymongo.read_concern.ReadConcern`. If ``None`` (the
329
+ default) the :attr:`read_concern` of this :class:`Database` is
330
+ used.
331
+ - `collation` (optional): An instance of
332
+ :class:`~pymongo.collation.Collation`.
333
+ - `session` (optional): a
334
+ :class:`~pymongo.client_session.ClientSession`.
335
+ - ``check_exists`` (optional): if True (the default), send a listCollections command to
336
+ check if the collection already exists before creation.
337
+ - `**kwargs` (optional): additional keyword arguments will
338
+ be passed as options for the `create collection command`_
339
+
340
+ All optional `create collection command`_ parameters should be passed
341
+ as keyword arguments to this method. Valid options include, but are not
342
+ limited to:
343
+
344
+ - ``size`` (int): desired initial size for the collection (in
345
+ bytes). For capped collections this size is the max
346
+ size of the collection.
347
+ - ``capped`` (bool): if True, this is a capped collection
348
+ - ``max`` (int): maximum number of objects if capped (optional)
349
+ - ``timeseries`` (dict): a document specifying configuration options for
350
+ timeseries collections
351
+ - ``expireAfterSeconds`` (int): the number of seconds after which a
352
+ document in a timeseries collection expires
353
+ - ``validator`` (dict): a document specifying validation rules or expressions
354
+ for the collection
355
+ - ``validationLevel`` (str): how strictly to apply the
356
+ validation rules to existing documents during an update. The default level
357
+ is "strict"
358
+ - ``validationAction`` (str): whether to "error" on invalid documents
359
+ (the default) or just "warn" about the violations but allow invalid
360
+ documents to be inserted
361
+ - ``indexOptionDefaults`` (dict): a document specifying a default configuration
362
+ for indexes when creating a collection
363
+ - ``viewOn`` (str): the name of the source collection or view from which
364
+ to create the view
365
+ - ``pipeline`` (list): a list of aggregation pipeline stages
366
+ - ``comment`` (str): a user-provided comment to attach to this command.
367
+ This option is only supported on MongoDB >= 4.4.
368
+ - ``encryptedFields`` (dict): **(BETA)** Document that describes the encrypted fields for
369
+ Queryable Encryption. For example::
370
+
371
+ {
372
+ "escCollection": "enxcol_.encryptedCollection.esc",
373
+ "eccCollection": "enxcol_.encryptedCollection.ecc",
374
+ "ecocCollection": "enxcol_.encryptedCollection.ecoc",
375
+ "fields": [
376
+ {
377
+ "path": "firstName",
378
+ "keyId": Binary.from_uuid(UUID('00000000-0000-0000-0000-000000000000')),
379
+ "bsonType": "string",
380
+ "queries": {"queryType": "equality"}
381
+ },
382
+ {
383
+ "path": "ssn",
384
+ "keyId": Binary.from_uuid(UUID('04104104-1041-0410-4104-104104104104')),
385
+ "bsonType": "string"
386
+ }
387
+ ]
388
+ }
389
+ - ``clusteredIndex`` (dict): Document that specifies the clustered index
390
+ configuration. It must have the following form::
391
+
392
+ {
393
+ // key pattern must be {_id: 1}
394
+ key: <key pattern>, // required
395
+ unique: <bool>, // required, must be ‘true’
396
+ name: <string>, // optional, otherwise automatically generated
397
+ v: <int>, // optional, must be ‘2’ if provided
398
+ }
399
+ - ``changeStreamPreAndPostImages`` (dict): a document with a boolean field ``enabled`` for
400
+ enabling pre- and post-images.
401
+
402
+ .. versionchanged:: 4.2
403
+ Added the ``check_exists``, ``clusteredIndex``, and ``encryptedFields`` parameters.
404
+
405
+ .. versionchanged:: 3.11
406
+ This method is now supported inside multi-document transactions
407
+ with MongoDB 4.4+.
408
+
409
+ .. versionchanged:: 3.6
410
+ Added ``session`` parameter.
411
+
412
+ .. versionchanged:: 3.4
413
+ Added the collation option.
414
+
415
+ .. versionchanged:: 3.0
416
+ Added the codec_options, read_preference, and write_concern options.
417
+
418
+ .. _create collection command:
419
+ https://mongodb.com/docs/manual/reference/command/create
420
+ """
421
+ encrypted_fields = kwargs.get("encryptedFields")
422
+ if (
423
+ not encrypted_fields
424
+ and self.client.options.auto_encryption_opts
425
+ and self.client.options.auto_encryption_opts._encrypted_fields_map
426
+ ):
427
+ encrypted_fields = self.client.options.auto_encryption_opts._encrypted_fields_map.get(
428
+ "%s.%s" % (self.name, name)
429
+ )
430
+ kwargs["encryptedFields"] = encrypted_fields
431
+
432
+ if encrypted_fields:
433
+ common.validate_is_mapping("encryptedFields", encrypted_fields)
434
+
435
+ clustered_index = kwargs.get("clusteredIndex")
436
+ if clustered_index:
437
+ common.validate_is_mapping("clusteredIndex", clustered_index)
438
+
439
+ with self.__client._tmp_session(session) as s:
440
+ # Skip this check in a transaction where listCollections is not
441
+ # supported.
442
+ if (
443
+ check_exists
444
+ and (not s or not s.in_transaction)
445
+ and name in self.list_collection_names(filter={"name": name}, session=s)
446
+ ):
447
+ raise CollectionInvalid("collection %s already exists" % name)
448
+ return Collection(
449
+ self,
450
+ name,
451
+ True,
452
+ codec_options,
453
+ read_preference,
454
+ write_concern,
455
+ read_concern,
456
+ session=s,
457
+ **kwargs,
458
+ )
459
+
460
+ def aggregate(
461
+ self, pipeline: _Pipeline, session: Optional["ClientSession"] = None, **kwargs: Any
462
+ ) -> CommandCursor[_DocumentType]:
463
+ """Perform a database-level aggregation.
464
+
465
+ See the `aggregation pipeline`_ documentation for a list of stages
466
+ that are supported.
467
+
468
+ .. code-block:: python
469
+
470
+ # Lists all operations currently running on the server.
471
+ with client.admin.aggregate([{"$currentOp": {}}]) as cursor:
472
+ for operation in cursor:
473
+ print(operation)
474
+
475
+ The :meth:`aggregate` method obeys the :attr:`read_preference` of this
476
+ :class:`Database`, except when ``$out`` or ``$merge`` are used, in
477
+ which case :attr:`~pymongo.read_preferences.ReadPreference.PRIMARY`
478
+ is used.
479
+
480
+ .. note:: This method does not support the 'explain' option. Please
481
+ use :meth:`~pymongo.database.Database.command` instead.
482
+
483
+ .. note:: The :attr:`~pymongo.database.Database.write_concern` of
484
+ this collection is automatically applied to this operation.
485
+
486
+ :Parameters:
487
+ - `pipeline`: a list of aggregation pipeline stages
488
+ - `session` (optional): a
489
+ :class:`~pymongo.client_session.ClientSession`.
490
+ - `**kwargs` (optional): extra `aggregate command`_ parameters.
491
+
492
+ All optional `aggregate command`_ parameters should be passed as
493
+ keyword arguments to this method. Valid options include, but are not
494
+ limited to:
495
+
496
+ - `allowDiskUse` (bool): Enables writing to temporary files. When set
497
+ to True, aggregation stages can write data to the _tmp subdirectory
498
+ of the --dbpath directory. The default is False.
499
+ - `maxTimeMS` (int): The maximum amount of time to allow the operation
500
+ to run in milliseconds.
501
+ - `batchSize` (int): The maximum number of documents to return per
502
+ batch. Ignored if the connected mongod or mongos does not support
503
+ returning aggregate results using a cursor.
504
+ - `collation` (optional): An instance of
505
+ :class:`~pymongo.collation.Collation`.
506
+ - `let` (dict): A dict of parameter names and values. Values must be
507
+ constant or closed expressions that do not reference document
508
+ fields. Parameters can then be accessed as variables in an
509
+ aggregate expression context (e.g. ``"$$var"``). This option is
510
+ only supported on MongoDB >= 5.0.
511
+
512
+ :Returns:
513
+ A :class:`~pymongo.command_cursor.CommandCursor` over the result
514
+ set.
515
+
516
+ .. versionadded:: 3.9
517
+
518
+ .. _aggregation pipeline:
519
+ https://mongodb.com/docs/manual/reference/operator/aggregation-pipeline
520
+
521
+ .. _aggregate command:
522
+ https://mongodb.com/docs/manual/reference/command/aggregate
523
+ """
524
+ with self.client._tmp_session(session, close=False) as s:
525
+ cmd = _DatabaseAggregationCommand(
526
+ self,
527
+ CommandCursor,
528
+ pipeline,
529
+ kwargs,
530
+ session is not None,
531
+ user_fields={"cursor": {"firstBatch": 1}},
532
+ )
533
+ return self.client._retryable_read(
534
+ cmd.get_cursor, cmd.get_read_preference(s), s, retryable=not cmd._performs_write
535
+ )
536
+
537
+ def watch(
538
+ self,
539
+ pipeline: Optional[_Pipeline] = None,
540
+ full_document: Optional[str] = None,
541
+ resume_after: Optional[Mapping[str, Any]] = None,
542
+ max_await_time_ms: Optional[int] = None,
543
+ batch_size: Optional[int] = None,
544
+ collation: Optional[_CollationIn] = None,
545
+ start_at_operation_time: Optional[Timestamp] = None,
546
+ session: Optional["ClientSession"] = None,
547
+ start_after: Optional[Mapping[str, Any]] = None,
548
+ comment: Optional[Any] = None,
549
+ full_document_before_change: Optional[str] = None,
550
+ ) -> DatabaseChangeStream[_DocumentType]:
551
+ """Watch changes on this database.
552
+
553
+ Performs an aggregation with an implicit initial ``$changeStream``
554
+ stage and returns a
555
+ :class:`~pymongo.change_stream.DatabaseChangeStream` cursor which
556
+ iterates over changes on all collections in this database.
557
+
558
+ Introduced in MongoDB 4.0.
559
+
560
+ .. code-block:: python
561
+
562
+ with db.watch() as stream:
563
+ for change in stream:
564
+ print(change)
565
+
566
+ The :class:`~pymongo.change_stream.DatabaseChangeStream` iterable
567
+ blocks until the next change document is returned or an error is
568
+ raised. If the
569
+ :meth:`~pymongo.change_stream.DatabaseChangeStream.next` method
570
+ encounters a network error when retrieving a batch from the server,
571
+ it will automatically attempt to recreate the cursor such that no
572
+ change events are missed. Any error encountered during the resume
573
+ attempt indicates there may be an outage and will be raised.
574
+
575
+ .. code-block:: python
576
+
577
+ try:
578
+ with db.watch(
579
+ [{'$match': {'operationType': 'insert'}}]) as stream:
580
+ for insert_change in stream:
581
+ print(insert_change)
582
+ except pymongo.errors.PyMongoError:
583
+ # The ChangeStream encountered an unrecoverable error or the
584
+ # resume attempt failed to recreate the cursor.
585
+ logging.error('...')
586
+
587
+ For a precise description of the resume process see the
588
+ `change streams specification`_.
589
+
590
+ :Parameters:
591
+ - `pipeline` (optional): A list of aggregation pipeline stages to
592
+ append to an initial ``$changeStream`` stage. Not all
593
+ pipeline stages are valid after a ``$changeStream`` stage, see the
594
+ MongoDB documentation on change streams for the supported stages.
595
+ - `full_document` (optional): The fullDocument to pass as an option
596
+ to the ``$changeStream`` stage. Allowed values: 'updateLookup',
597
+ 'whenAvailable', 'required'. When set to 'updateLookup', the
598
+ change notification for partial updates will include both a delta
599
+ describing the changes to the document, as well as a copy of the
600
+ entire document that was changed from some time after the change
601
+ occurred.
602
+ - `full_document_before_change`: Allowed values: 'whenAvailable'
603
+ and 'required'. Change events may now result in a
604
+ 'fullDocumentBeforeChange' response field.
605
+ - `resume_after` (optional): A resume token. If provided, the
606
+ change stream will start returning changes that occur directly
607
+ after the operation specified in the resume token. A resume token
608
+ is the _id value of a change document.
609
+ - `max_await_time_ms` (optional): The maximum time in milliseconds
610
+ for the server to wait for changes before responding to a getMore
611
+ operation.
612
+ - `batch_size` (optional): The maximum number of documents to return
613
+ per batch.
614
+ - `collation` (optional): The :class:`~pymongo.collation.Collation`
615
+ to use for the aggregation.
616
+ - `start_at_operation_time` (optional): If provided, the resulting
617
+ change stream will only return changes that occurred at or after
618
+ the specified :class:`~bson.timestamp.Timestamp`. Requires
619
+ MongoDB >= 4.0.
620
+ - `session` (optional): a
621
+ :class:`~pymongo.client_session.ClientSession`.
622
+ - `start_after` (optional): The same as `resume_after` except that
623
+ `start_after` can resume notifications after an invalidate event.
624
+ This option and `resume_after` are mutually exclusive.
625
+ - `comment` (optional): A user-provided comment to attach to this
626
+ command.
627
+
628
+ :Returns:
629
+ A :class:`~pymongo.change_stream.DatabaseChangeStream` cursor.
630
+
631
+ .. versionchanged:: 4.2
632
+ Added ``full_document_before_change`` parameter.
633
+
634
+ .. versionchanged:: 4.1
635
+ Added ``comment`` parameter.
636
+
637
+ .. versionchanged:: 3.9
638
+ Added the ``start_after`` parameter.
639
+
640
+ .. versionadded:: 3.7
641
+
642
+ .. seealso:: The MongoDB documentation on `changeStreams <https://mongodb.com/docs/manual/changeStreams/>`_.
643
+
644
+ .. _change streams specification:
645
+ https://github.com/mongodb/specifications/blob/master/source/change-streams/change-streams.rst
646
+ """
647
+ return DatabaseChangeStream(
648
+ self,
649
+ pipeline,
650
+ full_document,
651
+ resume_after,
652
+ max_await_time_ms,
653
+ batch_size,
654
+ collation,
655
+ start_at_operation_time,
656
+ session,
657
+ start_after,
658
+ comment,
659
+ full_document_before_change,
660
+ )
661
+
662
+ def _command(
663
+ self,
664
+ sock_info,
665
+ command,
666
+ value=1,
667
+ check=True,
668
+ allowable_errors=None,
669
+ read_preference=ReadPreference.PRIMARY,
670
+ codec_options=DEFAULT_CODEC_OPTIONS,
671
+ write_concern=None,
672
+ parse_write_concern_error=False,
673
+ session=None,
674
+ **kwargs,
675
+ ):
676
+ """Internal command helper."""
677
+ if isinstance(command, str):
678
+ command = SON([(command, value)])
679
+
680
+ command.update(kwargs)
681
+ with self.__client._tmp_session(session) as s:
682
+ return sock_info.command(
683
+ self.__name,
684
+ command,
685
+ read_preference,
686
+ codec_options,
687
+ check,
688
+ allowable_errors,
689
+ write_concern=write_concern,
690
+ parse_write_concern_error=parse_write_concern_error,
691
+ session=s,
692
+ client=self.__client,
693
+ )
694
+
695
+ @_csot.apply
696
+ def command(
697
+ self,
698
+ command: Union[str, MutableMapping[str, Any]],
699
+ value: Any = 1,
700
+ check: bool = True,
701
+ allowable_errors: Optional[Sequence[Union[str, int]]] = None,
702
+ read_preference: Optional[_ServerMode] = None,
703
+ codec_options: "Optional[bson.codec_options.CodecOptions[_CodecDocumentType]]" = None,
704
+ session: Optional["ClientSession"] = None,
705
+ comment: Optional[Any] = None,
706
+ **kwargs: Any,
707
+ ) -> _CodecDocumentType:
708
+ """Issue a MongoDB command.
709
+
710
+ Send command `command` to the database and return the
711
+ response. If `command` is an instance of :class:`basestring`
712
+ (:class:`str` in python 3) then the command {`command`: `value`}
713
+ will be sent. Otherwise, `command` must be an instance of
714
+ :class:`dict` and will be sent as is.
715
+
716
+ Any additional keyword arguments will be added to the final
717
+ command document before it is sent.
718
+
719
+ For example, a command like ``{buildinfo: 1}`` can be sent
720
+ using:
721
+
722
+ >>> db.command("buildinfo")
723
+
724
+ For a command where the value matters, like ``{collstats:
725
+ collection_name}`` we can do:
726
+
727
+ >>> db.command("collstats", collection_name)
728
+
729
+ For commands that take additional arguments we can use
730
+ kwargs. So ``{filemd5: object_id, root: file_root}`` becomes:
731
+
732
+ >>> db.command("filemd5", object_id, root=file_root)
733
+
734
+ :Parameters:
735
+ - `command`: document representing the command to be issued,
736
+ or the name of the command (for simple commands only).
737
+
738
+ .. note:: the order of keys in the `command` document is
739
+ significant (the "verb" must come first), so commands
740
+ which require multiple keys (e.g. `findandmodify`)
741
+ should use an instance of :class:`~bson.son.SON` or
742
+ a string and kwargs instead of a Python `dict`.
743
+
744
+ - `value` (optional): value to use for the command verb when
745
+ `command` is passed as a string
746
+ - `check` (optional): check the response for errors, raising
747
+ :class:`~pymongo.errors.OperationFailure` if there are any
748
+ - `allowable_errors`: if `check` is ``True``, error messages
749
+ in this list will be ignored by error-checking
750
+ - `read_preference` (optional): The read preference for this
751
+ operation. See :mod:`~pymongo.read_preferences` for options.
752
+ If the provided `session` is in a transaction, defaults to the
753
+ read preference configured for the transaction.
754
+ Otherwise, defaults to
755
+ :attr:`~pymongo.read_preferences.ReadPreference.PRIMARY`.
756
+ - `codec_options`: A :class:`~bson.codec_options.CodecOptions`
757
+ instance.
758
+ - `session` (optional): A
759
+ :class:`~pymongo.client_session.ClientSession`.
760
+ - `comment` (optional): A user-provided comment to attach to this
761
+ command.
762
+ - `**kwargs` (optional): additional keyword arguments will
763
+ be added to the command document before it is sent
764
+
765
+
766
+ .. note:: :meth:`command` does **not** obey this Database's
767
+ :attr:`read_preference` or :attr:`codec_options`. You must use the
768
+ ``read_preference`` and ``codec_options`` parameters instead.
769
+
770
+ .. note:: :meth:`command` does **not** apply any custom TypeDecoders
771
+ when decoding the command response.
772
+
773
+ .. note:: If this client has been configured to use MongoDB Stable
774
+ API (see :ref:`versioned-api-ref`), then :meth:`command` will
775
+ automatically add API versioning options to the given command.
776
+ Explicitly adding API versioning options in the command and
777
+ declaring an API version on the client is not supported.
778
+
779
+ .. versionchanged:: 3.6
780
+ Added ``session`` parameter.
781
+
782
+ .. versionchanged:: 3.0
783
+ Removed the `as_class`, `fields`, `uuid_subtype`, `tag_sets`,
784
+ and `secondary_acceptable_latency_ms` option.
785
+ Removed `compile_re` option: PyMongo now always represents BSON
786
+ regular expressions as :class:`~bson.regex.Regex` objects. Use
787
+ :meth:`~bson.regex.Regex.try_compile` to attempt to convert from a
788
+ BSON regular expression to a Python regular expression object.
789
+ Added the ``codec_options`` parameter.
790
+
791
+ .. seealso:: The MongoDB documentation on `commands <https://dochub.mongodb.org/core/commands>`_.
792
+ """
793
+ opts = codec_options or DEFAULT_CODEC_OPTIONS
794
+ if comment is not None:
795
+ kwargs["comment"] = comment
796
+
797
+ if read_preference is None:
798
+ read_preference = (session and session._txn_read_preference()) or ReadPreference.PRIMARY
799
+ with self.__client._socket_for_reads(read_preference, session) as (
800
+ sock_info,
801
+ read_preference,
802
+ ):
803
+ return self._command(
804
+ sock_info,
805
+ command,
806
+ value,
807
+ check,
808
+ allowable_errors,
809
+ read_preference,
810
+ opts,
811
+ session=session,
812
+ **kwargs,
813
+ )
814
+
815
+ def _retryable_read_command(
816
+ self,
817
+ command,
818
+ value=1,
819
+ check=True,
820
+ allowable_errors=None,
821
+ read_preference=None,
822
+ codec_options=DEFAULT_CODEC_OPTIONS,
823
+ session=None,
824
+ **kwargs,
825
+ ):
826
+ """Same as command but used for retryable read commands."""
827
+ if read_preference is None:
828
+ read_preference = (session and session._txn_read_preference()) or ReadPreference.PRIMARY
829
+
830
+ def _cmd(session, server, sock_info, read_preference):
831
+ return self._command(
832
+ sock_info,
833
+ command,
834
+ value,
835
+ check,
836
+ allowable_errors,
837
+ read_preference,
838
+ codec_options,
839
+ session=session,
840
+ **kwargs,
841
+ )
842
+
843
+ return self.__client._retryable_read(_cmd, read_preference, session)
844
+
845
+ def _list_collections(self, sock_info, session, read_preference, **kwargs):
846
+ """Internal listCollections helper."""
847
+
848
+ coll = self.get_collection("$cmd", read_preference=read_preference)
849
+ cmd = SON([("listCollections", 1), ("cursor", {})])
850
+ cmd.update(kwargs)
851
+ with self.__client._tmp_session(session, close=False) as tmp_session:
852
+ cursor = self._command(
853
+ sock_info, cmd, read_preference=read_preference, session=tmp_session
854
+ )["cursor"]
855
+ cmd_cursor = CommandCursor(
856
+ coll,
857
+ cursor,
858
+ sock_info.address,
859
+ session=tmp_session,
860
+ explicit_session=session is not None,
861
+ comment=cmd.get("comment"),
862
+ )
863
+ cmd_cursor._maybe_pin_connection(sock_info)
864
+ return cmd_cursor
865
+
866
+ def list_collections(
867
+ self,
868
+ session: Optional["ClientSession"] = None,
869
+ filter: Optional[Mapping[str, Any]] = None,
870
+ comment: Optional[Any] = None,
871
+ **kwargs: Any,
872
+ ) -> CommandCursor[Dict[str, Any]]:
873
+ """Get a cursor over the collections of this database.
874
+
875
+ :Parameters:
876
+ - `session` (optional): a
877
+ :class:`~pymongo.client_session.ClientSession`.
878
+ - `filter` (optional): A query document to filter the list of
879
+ collections returned from the listCollections command.
880
+ - `comment` (optional): A user-provided comment to attach to this
881
+ command.
882
+ - `**kwargs` (optional): Optional parameters of the
883
+ `listCollections command
884
+ <https://mongodb.com/docs/manual/reference/command/listCollections/>`_
885
+ can be passed as keyword arguments to this method. The supported
886
+ options differ by server version.
887
+
888
+
889
+ :Returns:
890
+ An instance of :class:`~pymongo.command_cursor.CommandCursor`.
891
+
892
+ .. versionadded:: 3.6
893
+ """
894
+ if filter is not None:
895
+ kwargs["filter"] = filter
896
+ read_pref = (session and session._txn_read_preference()) or ReadPreference.PRIMARY
897
+ if comment is not None:
898
+ kwargs["comment"] = comment
899
+
900
+ def _cmd(session, server, sock_info, read_preference):
901
+ return self._list_collections(
902
+ sock_info, session, read_preference=read_preference, **kwargs
903
+ )
904
+
905
+ return self.__client._retryable_read(_cmd, read_pref, session)
906
+
907
+ def list_collection_names(
908
+ self,
909
+ session: Optional["ClientSession"] = None,
910
+ filter: Optional[Mapping[str, Any]] = None,
911
+ comment: Optional[Any] = None,
912
+ **kwargs: Any,
913
+ ) -> List[str]:
914
+ """Get a list of all the collection names in this database.
915
+
916
+ For example, to list all non-system collections::
917
+
918
+ filter = {"name": {"$regex": r"^(?!system\\.)"}}
919
+ db.list_collection_names(filter=filter)
920
+
921
+ :Parameters:
922
+ - `session` (optional): a
923
+ :class:`~pymongo.client_session.ClientSession`.
924
+ - `filter` (optional): A query document to filter the list of
925
+ collections returned from the listCollections command.
926
+ - `comment` (optional): A user-provided comment to attach to this
927
+ command.
928
+ - `**kwargs` (optional): Optional parameters of the
929
+ `listCollections command
930
+ <https://mongodb.com/docs/manual/reference/command/listCollections/>`_
931
+ can be passed as keyword arguments to this method. The supported
932
+ options differ by server version.
933
+
934
+
935
+ .. versionchanged:: 3.8
936
+ Added the ``filter`` and ``**kwargs`` parameters.
937
+
938
+ .. versionadded:: 3.6
939
+ """
940
+ if comment is not None:
941
+ kwargs["comment"] = comment
942
+ if filter is None:
943
+ kwargs["nameOnly"] = True
944
+
945
+ else:
946
+ # The enumerate collections spec states that "drivers MUST NOT set
947
+ # nameOnly if a filter specifies any keys other than name."
948
+ common.validate_is_mapping("filter", filter)
949
+ kwargs["filter"] = filter
950
+ if not filter or (len(filter) == 1 and "name" in filter):
951
+ kwargs["nameOnly"] = True
952
+
953
+ return [result["name"] for result in self.list_collections(session=session, **kwargs)]
954
+
955
+ def _drop_helper(self, name, session=None, comment=None):
956
+ command = SON([("drop", name)])
957
+ if comment is not None:
958
+ command["comment"] = comment
959
+
960
+ with self.__client._socket_for_writes(session) as sock_info:
961
+ return self._command(
962
+ sock_info,
963
+ command,
964
+ allowable_errors=["ns not found", 26],
965
+ write_concern=self._write_concern_for(session),
966
+ parse_write_concern_error=True,
967
+ session=session,
968
+ )
969
+
970
+ @_csot.apply
971
+ def drop_collection(
972
+ self,
973
+ name_or_collection: Union[str, Collection],
974
+ session: Optional["ClientSession"] = None,
975
+ comment: Optional[Any] = None,
976
+ encrypted_fields: Optional[Mapping[str, Any]] = None,
977
+ ) -> Dict[str, Any]:
978
+ """Drop a collection.
979
+
980
+ :Parameters:
981
+ - `name_or_collection`: the name of a collection to drop or the
982
+ collection object itself
983
+ - `session` (optional): a
984
+ :class:`~pymongo.client_session.ClientSession`.
985
+ - `comment` (optional): A user-provided comment to attach to this
986
+ command.
987
+ - `encrypted_fields`: **(BETA)** Document that describes the encrypted fields for
988
+ Queryable Encryption. For example::
989
+
990
+ {
991
+ "escCollection": "enxcol_.encryptedCollection.esc",
992
+ "eccCollection": "enxcol_.encryptedCollection.ecc",
993
+ "ecocCollection": "enxcol_.encryptedCollection.ecoc",
994
+ "fields": [
995
+ {
996
+ "path": "firstName",
997
+ "keyId": Binary.from_uuid(UUID('00000000-0000-0000-0000-000000000000')),
998
+ "bsonType": "string",
999
+ "queries": {"queryType": "equality"}
1000
+ },
1001
+ {
1002
+ "path": "ssn",
1003
+ "keyId": Binary.from_uuid(UUID('04104104-1041-0410-4104-104104104104')),
1004
+ "bsonType": "string"
1005
+ }
1006
+ ]
1007
+
1008
+ }
1009
+
1010
+
1011
+ .. note:: The :attr:`~pymongo.database.Database.write_concern` of
1012
+ this database is automatically applied to this operation.
1013
+
1014
+ .. versionchanged:: 4.2
1015
+ Added ``encrypted_fields`` parameter.
1016
+
1017
+ .. versionchanged:: 4.1
1018
+ Added ``comment`` parameter.
1019
+
1020
+ .. versionchanged:: 3.6
1021
+ Added ``session`` parameter.
1022
+
1023
+ .. versionchanged:: 3.4
1024
+ Apply this database's write concern automatically to this operation
1025
+ when connected to MongoDB >= 3.4.
1026
+
1027
+ """
1028
+ name = name_or_collection
1029
+ if isinstance(name, Collection):
1030
+ name = name.name
1031
+
1032
+ if not isinstance(name, str):
1033
+ raise TypeError("name_or_collection must be an instance of str")
1034
+ full_name = "%s.%s" % (self.name, name)
1035
+ if (
1036
+ not encrypted_fields
1037
+ and self.client.options.auto_encryption_opts
1038
+ and self.client.options.auto_encryption_opts._encrypted_fields_map
1039
+ ):
1040
+ encrypted_fields = self.client.options.auto_encryption_opts._encrypted_fields_map.get(
1041
+ full_name
1042
+ )
1043
+ if not encrypted_fields and self.client.options.auto_encryption_opts:
1044
+ colls = list(
1045
+ self.list_collections(filter={"name": name}, session=session, comment=comment)
1046
+ )
1047
+ if colls and colls[0]["options"].get("encryptedFields"):
1048
+ encrypted_fields = colls[0]["options"]["encryptedFields"]
1049
+ if encrypted_fields:
1050
+ common.validate_is_mapping("encrypted_fields", encrypted_fields)
1051
+ self._drop_helper(
1052
+ _esc_coll_name(encrypted_fields, name), session=session, comment=comment
1053
+ )
1054
+ self._drop_helper(
1055
+ _ecc_coll_name(encrypted_fields, name), session=session, comment=comment
1056
+ )
1057
+ self._drop_helper(
1058
+ _ecoc_coll_name(encrypted_fields, name), session=session, comment=comment
1059
+ )
1060
+
1061
+ return self._drop_helper(name, session, comment)
1062
+
1063
+ def validate_collection(
1064
+ self,
1065
+ name_or_collection: Union[str, Collection],
1066
+ scandata: bool = False,
1067
+ full: bool = False,
1068
+ session: Optional["ClientSession"] = None,
1069
+ background: Optional[bool] = None,
1070
+ comment: Optional[Any] = None,
1071
+ ) -> Dict[str, Any]:
1072
+ """Validate a collection.
1073
+
1074
+ Returns a dict of validation info. Raises CollectionInvalid if
1075
+ validation fails.
1076
+
1077
+ See also the MongoDB documentation on the `validate command`_.
1078
+
1079
+ :Parameters:
1080
+ - `name_or_collection`: A Collection object or the name of a
1081
+ collection to validate.
1082
+ - `scandata`: Do extra checks beyond checking the overall
1083
+ structure of the collection.
1084
+ - `full`: Have the server do a more thorough scan of the
1085
+ collection. Use with `scandata` for a thorough scan
1086
+ of the structure of the collection and the individual
1087
+ documents.
1088
+ - `session` (optional): a
1089
+ :class:`~pymongo.client_session.ClientSession`.
1090
+ - `background` (optional): A boolean flag that determines whether
1091
+ the command runs in the background. Requires MongoDB 4.4+.
1092
+ - `comment` (optional): A user-provided comment to attach to this
1093
+ command.
1094
+
1095
+ .. versionchanged:: 4.1
1096
+ Added ``comment`` parameter.
1097
+
1098
+ .. versionchanged:: 3.11
1099
+ Added ``background`` parameter.
1100
+
1101
+ .. versionchanged:: 3.6
1102
+ Added ``session`` parameter.
1103
+
1104
+ .. _validate command: https://mongodb.com/docs/manual/reference/command/validate/
1105
+ """
1106
+ name = name_or_collection
1107
+ if isinstance(name, Collection):
1108
+ name = name.name
1109
+
1110
+ if not isinstance(name, str):
1111
+ raise TypeError("name_or_collection must be an instance of str or Collection")
1112
+ cmd = SON([("validate", name), ("scandata", scandata), ("full", full)])
1113
+ if comment is not None:
1114
+ cmd["comment"] = comment
1115
+
1116
+ if background is not None:
1117
+ cmd["background"] = background
1118
+
1119
+ result = cast(dict, self.command(cmd, session=session))
1120
+
1121
+ valid = True
1122
+ # Pre 1.9 results
1123
+ if "result" in result:
1124
+ info = result["result"]
1125
+ if info.find("exception") != -1 or info.find("corrupt") != -1:
1126
+ raise CollectionInvalid("%s invalid: %s" % (name, info))
1127
+ # Sharded results
1128
+ elif "raw" in result:
1129
+ for _, res in result["raw"].items():
1130
+ if "result" in res:
1131
+ info = res["result"]
1132
+ if info.find("exception") != -1 or info.find("corrupt") != -1:
1133
+ raise CollectionInvalid("%s invalid: %s" % (name, info))
1134
+ elif not res.get("valid", False):
1135
+ valid = False
1136
+ break
1137
+ # Post 1.9 non-sharded results.
1138
+ elif not result.get("valid", False):
1139
+ valid = False
1140
+
1141
+ if not valid:
1142
+ raise CollectionInvalid("%s invalid: %r" % (name, result))
1143
+
1144
+ return result
1145
+
1146
+ # See PYTHON-3084.
1147
+ __iter__ = None
1148
+
1149
+ def __next__(self) -> NoReturn:
1150
+ raise TypeError("'Database' object is not iterable")
1151
+
1152
+ next = __next__
1153
+
1154
+ def __bool__(self) -> NoReturn:
1155
+ raise NotImplementedError(
1156
+ "Database objects do not implement truth "
1157
+ "value testing or bool(). Please compare "
1158
+ "with None instead: database is not None"
1159
+ )
1160
+
1161
+ def dereference(
1162
+ self,
1163
+ dbref: DBRef,
1164
+ session: Optional["ClientSession"] = None,
1165
+ comment: Optional[Any] = None,
1166
+ **kwargs: Any,
1167
+ ) -> Optional[_DocumentType]:
1168
+ """Dereference a :class:`~bson.dbref.DBRef`, getting the
1169
+ document it points to.
1170
+
1171
+ Raises :class:`TypeError` if `dbref` is not an instance of
1172
+ :class:`~bson.dbref.DBRef`. Returns a document, or ``None`` if
1173
+ the reference does not point to a valid document. Raises
1174
+ :class:`ValueError` if `dbref` has a database specified that
1175
+ is different from the current database.
1176
+
1177
+ :Parameters:
1178
+ - `dbref`: the reference
1179
+ - `session` (optional): a
1180
+ :class:`~pymongo.client_session.ClientSession`.
1181
+ - `comment` (optional): A user-provided comment to attach to this
1182
+ command.
1183
+ - `**kwargs` (optional): any additional keyword arguments
1184
+ are the same as the arguments to
1185
+ :meth:`~pymongo.collection.Collection.find`.
1186
+
1187
+
1188
+ .. versionchanged:: 4.1
1189
+ Added ``comment`` parameter.
1190
+ .. versionchanged:: 3.6
1191
+ Added ``session`` parameter.
1192
+ """
1193
+ if not isinstance(dbref, DBRef):
1194
+ raise TypeError("cannot dereference a %s" % type(dbref))
1195
+ if dbref.database is not None and dbref.database != self.__name:
1196
+ raise ValueError(
1197
+ "trying to dereference a DBRef that points to "
1198
+ "another database (%r not %r)" % (dbref.database, self.__name)
1199
+ )
1200
+ return self[dbref.collection].find_one(
1201
+ {"_id": dbref.id}, session=session, comment=comment, **kwargs
1202
+ )