Skip to content

Commit 7d68a4b

Browse files
committed
DOCSP-47951 - Remove troubleshooting page (#190)
(cherry picked from commit 39f0059) (cherry picked from commit 9997e3a)
1 parent ff0c8a1 commit 7d68a4b

File tree

6 files changed

+238
-268
lines changed

6 files changed

+238
-268
lines changed

source/connect/connection-targets.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,38 @@ Troubleshooting
156156

157157
.. include:: /includes/troubleshooting/connection-targets.rst
158158

159+
Timeout When Accessing MongoDB from {+driver-short+} with Tunneling
160+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
161+
162+
If you try to connect to a MongoDB replica set over an SSH tunnel, you
163+
receive the following error:
164+
165+
.. code-block:: python
166+
167+
File "/Library/Python/2.7/site-packages/pymongo/collection.py", line 1560, in count
168+
return self._count(cmd, collation, session)
169+
File "/Library/Python/2.7/site-packages/pymongo/collection.py", line 1504, in _count
170+
with self._socket_for_reads() as (connection, slave_ok):
171+
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/contextlib.py", line 17, in __enter__
172+
return self.gen.next()
173+
File "/Library/Python/2.7/site-packages/pymongo/mongo_client.py", line 982, in _socket_for_reads
174+
server = topology.select_server(read_preference)
175+
File "/Library/Python/2.7/site-packages/pymongo/topology.py", line 224, in select_server
176+
address))
177+
File "/Library/Python/2.7/site-packages/pymongo/topology.py", line 183, in select_servers
178+
selector, server_timeout, address)
179+
File "/Library/Python/2.7/site-packages/pymongo/topology.py", line 199, in _select_servers_loop
180+
self._error_message(selector))
181+
pymongo.errors.ServerSelectionTimeoutError: localhost:27017: timed out
182+
183+
This occurs because {+driver-short+} discovers replica set members by using the response
184+
from the ``isMaster`` command, which contains the addresses and ports of the other
185+
replica set members. However, you can't access these addresses and ports through the SSH
186+
tunnel.
187+
188+
Instead, you can connect directly to a single MongoDB node by using the
189+
``directConnection=True`` option with SSH tunneling.
190+
159191
API Documentation
160192
-----------------
161193

source/connect/mongoclient.txt

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ child process.
199199
a high probability of deadlock among ``MongoClient`` instances in the child process.
200200
{+driver-short+} tries to issue a warning if this deadlock might occur.
201201

202+
For more information about deadlock in forked processes, see
203+
:ref:`pymongo-fork-deadlock`.
204+
202205
Multiprocessing
203206
~~~~~~~~~~~~~~~
204207

@@ -223,6 +226,93 @@ To use multiprocessing with {+driver-short+}, write code similar to the followin
223226
Do not copy an instance of the ``MongoClient`` class from the parent process to a child
224227
process.
225228

229+
Type Hints
230+
----------
231+
232+
If you're using Python v3.5 or later, you can add type hints to your Python code.
233+
234+
The following code example shows how to declare a type hint for a ``MongoClient``
235+
object:
236+
237+
.. code-block:: python
238+
239+
client: MongoClient = MongoClient()
240+
241+
In the previous example, the code doesn't specify a type for the documents that the
242+
``MongoClient`` object will work with. To specify a document type,
243+
include the ``Dict[str, Any]`` type when you
244+
create the ``MongoClient`` object, as shown in the following example:
245+
246+
.. code-block:: python
247+
248+
from typing import Any, Dict
249+
client: MongoClient[Dict[str, Any]] = MongoClient()
250+
251+
Troubleshooting
252+
---------------
253+
254+
MongoClient Fails ConfigurationError
255+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
256+
257+
Providing invalid keyword argument names causes the driver to raise this error.
258+
259+
Ensure that the keyword arguments that you specify exist and are
260+
spelled correctly.
261+
262+
.. _pymongo-fork-deadlock:
263+
264+
Forking a Process Causes a Deadlock
265+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
266+
267+
A ``MongoClient`` instance spawns multiple threads to run background tasks, such as
268+
monitoring connected servers. These threads share state that is protected by instances
269+
of the ``threading.Lock`` class, which are themselves
270+
`not fork-safe <http://bugs.python.org/issue6721>`__.
271+
{+driver-short+} is subject to the same limitations as any other multithreaded
272+
code that uses the ``threading.Lock`` class, or any mutexes.
273+
274+
One of these limitations is that the locks become useless after calling the
275+
``fork()`` method. When ``fork()`` executes, the driver copies all the parent process's locks to
276+
the child process in the same state as they were in the parent. If they are
277+
locked in the parent process, they are also locked in the child process. The child process
278+
created by ``fork()`` has only one thread, so any locks created by
279+
other threads in the parent process are never released in the child process.
280+
The next time the child process attempts to acquire one of these locks, deadlock occurs.
281+
282+
Starting in {+driver-short+} version 4.3, after you call the ``os.fork()`` method, the
283+
driver uses the ``os.register_at_fork()`` method to reset its locks and other shared state
284+
in the child process. Although this reduces the likelihood of a deadlock,
285+
{+driver-short+} depends
286+
on libraries that aren't fork-safe in multithreaded applications, including
287+
`OpenSSL <https://github.com/openssl/openssl/issues/19066>`__ and
288+
`getaddrinfo(3). <https://man7.org/linux/man-pages/man3/gai_strerror.3.html>`__
289+
Therefore, a deadlock can still occur.
290+
291+
The Linux manual page for `fork(2) <https://man7.org/linux/man-pages/man2/fork.2.html>`__
292+
also imposes the following restriction:
293+
294+
.. blockquote::
295+
296+
After a ``fork()`` in a multithreaded program, the child can
297+
safely call only async-signal-safe functions (see
298+
`signal-safety(7) <https://man7.org/linux/man-pages/man7/signal-safety.7.html>`__)
299+
until such time as it calls
300+
`execve(2) <https://man7.org/linux/man-pages/man2/execve.2.html>`__.
301+
302+
Because {+driver-short+} relies on functions that are *not*
303+
async-signal-safe, it can cause deadlocks or crashes when running in a child
304+
process.
305+
306+
.. tip::
307+
308+
For an example of a deadlock in a child process, see
309+
`PYTHON-3406 <https://jira.mongodb.org/browse/PYTHON-3406>`__ in Jira.
310+
311+
For more information about the problems caused by Python locks in
312+
multithreaded contexts with ``fork()``, see `Issue 6721 <http://bugs.python.org/issue6721>`__
313+
in the Python Issue Tracker.
314+
315+
226316
API Documentation
227317
-----------------
228318

source/connect/tls.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,10 @@ To disable only hostname verification, set the ``tlsAllowInvalidHostnames`` opti
231231
vulnerable to expired certificates and to foreign processes posing
232232
as valid client instances.
233233

234-
Troubleshoot TLS
235-
----------------
234+
.. _pymongo-troubleshoot-tls:
235+
236+
Troubleshooting
237+
---------------
236238

237239
.. include:: /includes/troubleshooting/tls.rst
238240

source/data-formats/dates-and-times.txt

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,76 @@ at the beginning and end of the allowed range.
440440
datetime before the range: {"date": datetime.datetime(1, 1, 1, 0, 0)}
441441
datetime after the range: {"date": datetime.datetime(9999, 12, 31, 23, 59, 59, 999000)}
442442

443+
Troubleshooting
444+
---------------
445+
446+
OverflowError When Decoding Dates Stored by Another Language's Driver
447+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
448+
449+
{+driver-short+} decodes BSON ``datetime`` values to instances of Python's
450+
``datetime.datetime`` class. Instances of ``datetime.datetime`` are
451+
limited to years between ``datetime.MINYEAR`` (1) and
452+
``datetime.MAXYEAR`` (9999). Some MongoDB drivers
453+
can store BSON datetimes with year values far outside those supported
454+
by ``datetime.datetime``.
455+
456+
There are a few ways to work around this issue. Starting with {+driver-short+} 4.3,
457+
``bson.decode`` can decode BSON ``datetime`` values in one of four ways. You can specify
458+
the conversion method by using ``datetime_conversion`` parameter of
459+
``~bson.codec_options.CodecOptions``.
460+
461+
The default conversion option is
462+
``~bson.codec_options.DatetimeConversion.DATETIME``, which will
463+
attempt to decode the value as a ``datetime.datetime``, allowing
464+
``~builtin.OverflowError`` to occur for out-of-range dates.
465+
``~bson.codec_options.DatetimeConversion.DATETIME_AUTO`` alters
466+
this behavior to instead return ``~bson.datetime_ms.DatetimeMS`` when
467+
representations are out-of-range, while returning ``~datetime.datetime``
468+
objects as before:
469+
470+
.. io-code-block::
471+
472+
.. input::
473+
:language: python
474+
475+
from datetime import datetime
476+
from bson.datetime_ms import DatetimeMS
477+
from bson.codec_options import DatetimeConversion
478+
from pymongo import MongoClient
479+
480+
client = MongoClient(datetime_conversion=DatetimeConversion.DATETIME_AUTO)
481+
client.db.collection.insert_one({"x": datetime(1970, 1, 1)})
482+
483+
client.db.collection.insert_one({"x": DatetimeMS(2**62)})
484+
485+
for x in client.db.collection.find():
486+
print(x)
487+
488+
.. output::
489+
490+
{'_id': ObjectId('...'), 'x': datetime.datetime(1970, 1, 1, 0, 0)}
491+
{'_id': ObjectId('...'), 'x': DatetimeMS(4611686018427387904)}
492+
493+
For other options, see the API documentation for the
494+
`DatetimeConversion <{+api-root+}bson/codec_options.html#bson.codec_options.DatetimeConversion>`__
495+
class.
496+
497+
Another option that does not involve setting ``datetime_conversion`` is to
498+
filter out document values outside of the range supported by
499+
``~datetime.datetime``:
500+
501+
.. code-block:: python
502+
503+
from datetime import datetime
504+
coll = client.test.dates
505+
cur = coll.find({'dt': {'$gte': datetime.min, '$lte': datetime.max}})
506+
507+
If you don't need the value of ``datetime``, you can filter out just that field:
508+
509+
.. code-block:: python
510+
511+
cur = coll.find({}, projection={'dt': False})
512+
443513
API Documentation
444514
-----------------
445515

source/read/specify-a-query.txt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,48 @@ all documents with a ``name`` field value that has at least two consecutive
238238
{'_id': 1, 'name': 'apples', 'qty': 5, 'rating': 3, 'color': 'red', 'type': ['fuji', 'honeycrisp']}
239239
{'_id': 4, 'name': 'pineapple', 'qty': 3, 'rating': 5, 'color': 'yellow'}
240240

241+
Troubleshooting
242+
---------------
243+
244+
.. _web-application-querying-by-objectid:
245+
246+
No Results When Querying for a Document by ObjectId in Web Applications
247+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
248+
249+
It's common in web applications to encode documents' ObjectIds in URLs, as shown
250+
in the following code example:
251+
252+
.. code-block:: python
253+
254+
"/posts/50b3bda58a02fb9a84d8991e"
255+
256+
Your web framework passes the ObjectId part of the URL to your request
257+
handler as a string. You must convert the string to an ``ObjectId`` instance
258+
before passing it to the ``find_one()`` method.
259+
260+
The following code example shows how to perform this conversion in a
261+
`Flask <http://flask.pocoo.org/>`__ application. The process is similar for other web
262+
frameworks.
263+
264+
.. code-block:: python
265+
266+
from pymongo import MongoClient
267+
from bson.objectid import ObjectId
268+
269+
from flask import Flask, render_template
270+
271+
client = MongoClient()
272+
app = Flask(__name__)
273+
274+
@app.route("/posts/<_id>")
275+
def show_post(_id):
276+
# NOTE!: converting _id from string to ObjectId before passing to find_one
277+
post = client.db.posts.find_one({'_id': ObjectId(_id)})
278+
return render_template('post.html', post=post)
279+
280+
if __name__ == "__main__":
281+
app.run()
282+
241283
Additional Information
242284
----------------------
243285

0 commit comments

Comments
 (0)