Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is PyMongo 3 giving ServerSelectionTimeoutError?

I'm using:

  • Python 3.4.2
  • PyMongo 3.0.2
  • mongolab running mongod 2.6.9
  • uWSGI 2.0.10
  • CherryPy 3.7.0
  • nginx 1.6.2

uWSGI start params:

--socket 127.0.0.1:8081 --daemonize --enable-threads --threads 2 --processes 2

I setup my MongoClient ONE time:

self.mongo_client = MongoClient('mongodb://user:[email protected]:port/mydb')
self.db = self.mongo_client['mydb']

I try and save a JSON dict to MongoDB:

result = self.db.jobs.insert_one(job_dict)

It works via a unit test that executes the same code path to mongodb. However when I execute via CherryPy and uWSGI using an HTTP POST, I get this:

pymongo.errors.ServerSelectionTimeoutError: No servers found yet

Why am I seeing this behavior when run via CherryPy and uWSGI? Is this perhaps the new thread model in PyMongo 3?

Update:

If I run without uWSGI and nginx by using the CherryPy built-in server, the insert_one() works.

Update 1/25 4:53pm EST:

After adding some debug in PyMongo, it appears that topology._update_servers() knows that the server_type = 2 for server 'myserver-a.mongolab.com'. However server_description.known_servers() has the server_type = 0 for server 'myserver.mongolab.com'

This leads to the following stack trace:

result = self.db.jobs.insert_one(job_dict)
File "/usr/local/lib/python3.4/site-packages/pymongo/collection.py", line 466, in insert_one
with self._socket_for_writes() as sock_info:
File "/usr/local/lib/python3.4/contextlib.py", line 59, in __enter__
return next(self.gen)
File "/usr/local/lib/python3.4/site-packages/pymongo/mongo_client.py", line 663, in _get_socket
server = self._get_topology().select_server(selector)
File "/usr/local/lib/python3.4/site-packages/pymongo/topology.py", line 121, in select_server
address))
File "/usr/local/lib/python3.4/site-packages/pymongo/topology.py", line 97, in select_servers
self._error_message(selector))
pymongo.errors.ServerSelectionTimeoutError: No servers found yet
like image 428
drfence Avatar asked Jun 24 '15 15:06

drfence


People also ask

What does find_One return PyMongo?

The find_One() method of pymongo is used to retrieve a single document based on your query, in case of no matches this method returns nothing and if you doesn't use any query it returns the first document of the collection.

What does Insert_one return PyMongo?

insert_one() Method This method returns an instance of class “~pymongo. results. InsertOneResult” which has a “_id” field that holds the id of the inserted document. If the document does not specify an “_id” field, then MongoDB will add the “_id” field and assign a unique object id for the document before inserting.

How do I get all documents in PyMongo?

To get all the Documents of the Collection use find() method. The find() method takes a query object as a parameter if we want to find all documents then pass none in the find() method.

Is PyMongo an ODM?

PyMODM is a “core” ODM, meaning that it provides simple, extensible functionality that can be leveraged by other libraries to target platforms like Django. At the same time, PyMODM is powerful enough to be used for developing applications on its own.


3 Answers

We're investigating this problem, tracked in PYTHON-961. You may be able to work around the issue by passing connect=False when creating instances of MongoClient. That defers background connection until the first database operation is attempted, avoiding what I suspect is a race condition between spin up of MongoClient's monitor thread and multiprocess forking.

like image 135
Bernie Hackett Avatar answered Oct 17 '22 22:10

Bernie Hackett


As mentioned here: https://stackoverflow.com/a/54314615/8953378

I added ?ssl=true&ssl_cert_reqs=CERT_NONE to my connection string, and it fixed the issue.

so instead of:

connection_string = "mongodb+srv://<USER>:<PASSWORD>@<CLUSTER>/<COLLECTION>"

I wrote:

connection_string = "mongodb+srv://<USER>:<PASSWORD>@<CLUSTER>/<COLLECTION>?ssl=true&ssl_cert_reqs=CERT_NONE"

(Note that if you have other parameters in your connection string, you need to change the ? to & )

like image 28
Alon Gouldman Avatar answered Oct 17 '22 21:10

Alon Gouldman


I fixed it for myself by downgrading from pymongo 3.0 to 2.8. No idea what's going on.

   flask/bin/pip uninstall pymongo
   flask/bin/pip install pymongo==2.8
like image 14
Greg Avatar answered Oct 17 '22 21:10

Greg