Skip to content

Commit 5686977

Browse files
committed
don't connect to MongoDB immediately (fixes #87)
1 parent d8b5587 commit 5686977

File tree

3 files changed

+28
-9
lines changed

3 files changed

+28
-9
lines changed

docs/index.rst

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,13 @@ constructor. These are passed directly through to the underlying
9191

9292
.. note::
9393

94-
Unless you specify otherwise, PyMongo will attempt to connect to your
95-
MongoDB server immediately (within the call to :meth:`init_app` in the
96-
case of Flask-PyMongo). If the web server you are running Flask in loads
97-
your application before forking, you may experience problems. In these
98-
cases, you are advised to pass ``connect=False`` to ``PyMongo``, or
99-
append ``?connect=false`` to your MongoDB URI.
94+
By default, Flask-PyMongo sets the ``connect`` keyword argument to
95+
``False``, to prevent PyMongo from connecting immediately. PyMongo
96+
itself `is not fork-safe
97+
<http://api.mongodb.com/python/current/faq.html#is-pymongo-fork-safe>`_,
98+
and delaying connection until the app is actually used is necessary to
99+
avoid issues. If you wish to change this default behavior, pass
100+
``connect=True`` as a keyword argument to ``PyMongo``.
100101

101102
You can create multiple ``PyMongo`` instances, to connect to multiple
102103
databases or database servers:
@@ -173,6 +174,7 @@ Changes:
173174
`issue #110 <https://github.com/dcrosta/flask-pymongo/issues/110>`_.
174175

175176
- Only support configuration via URI.
177+
- Don't connect to MongoDB by default.
176178
- Clarify version support of Python, Flask, PyMongo, and MongoDB.
177179
- Readability improvement to ``README.md`` (MinJae Kwon).
178180

flask_pymongo/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,10 @@ def init_app(self, app, uri=None, *args, **kwargs):
149149
parsed_uri = uri_parser.parse_uri(uri)
150150
database_name = parsed_uri["database"]
151151

152+
# Try to delay connecting, in case the app is loaded before forking, per
153+
# http://api.mongodb.com/python/current/faq.html#is-pymongo-fork-safe
154+
kwargs.setdefault("connect", False)
155+
152156
self.cx = MongoClient(*args, **kwargs)
153157
self.db = self.cx[database_name]
154158

flask_pymongo/tests/test_config.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import time
22

33
import pymongo
4+
import pytest
45

56
from flask_pymongo.tests.util import FlaskRequestTest
67
import flask_pymongo
78

89

10+
class CouldNotConnect(Exception):
11+
pass
12+
13+
914
class FlaskPyMongoConfigTest(FlaskRequestTest):
1015

1116
def setUp(self):
@@ -32,7 +37,7 @@ def test_config_with_uri_in_flask_conf_var(self):
3237
uri = "mongodb://localhost:{}/{}".format(self.port, self.dbname)
3338
self.app.config["MONGO_URI"] = uri
3439

35-
mongo = flask_pymongo.PyMongo(self.app)
40+
mongo = flask_pymongo.PyMongo(self.app, connect=True)
3641

3742
_wait_until_connected(mongo)
3843
assert mongo.db.name == self.dbname
@@ -41,7 +46,7 @@ def test_config_with_uri_in_flask_conf_var(self):
4146
def test_config_with_uri_passed_directly(self):
4247
uri = "mongodb://localhost:{}/{}".format(self.port, self.dbname)
4348

44-
mongo = flask_pymongo.PyMongo(self.app, uri)
49+
mongo = flask_pymongo.PyMongo(self.app, uri, connect=True)
4550

4651
_wait_until_connected(mongo)
4752
assert mongo.db.name == self.dbname
@@ -68,11 +73,19 @@ class CustomDict(dict):
6873

6974
assert type(mongo.db.things.find_one()) == CustomDict
7075

76+
def test_it_doesnt_connect_by_default(self):
77+
uri = "mongodb://localhost:{}/{}".format(self.port, self.dbname)
78+
79+
mongo = flask_pymongo.PyMongo(self.app, uri)
80+
81+
with pytest.raises(CouldNotConnect):
82+
_wait_until_connected(mongo, timeout=0.2)
83+
7184

7285
def _wait_until_connected(mongo, timeout=1.0):
7386
start = time.time()
7487
while time.time() < (start + timeout):
7588
if mongo.cx.nodes:
7689
return
7790
time.sleep(0.05)
78-
raise RuntimeError("could not prove mongodb connected in %r seconds" % timeout)
91+
raise CouldNotConnect("could not prove mongodb connected in %r seconds" % timeout)

0 commit comments

Comments
 (0)