From 697c3a5250800f4bb80279998cbefd6069794a22 Mon Sep 17 00:00:00 2001 From: "A. Jesse Jiryu Davis" Date: Thu, 16 Apr 2015 09:46:04 -0400 Subject: [PATCH 1/7] PyMongo 3 compatibility. "auto_start_request" option is gone, "max_pool_size" renamed to "maxPoolSize", "safe" is gone, "_connect" is renamed "connect". Closes issue #207. --- CHANGELOG.rst | 1 + django_mongodb_engine/base.py | 4 ---- docs/source/reference/settings.rst | 15 +++++---------- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2fde7c87..0eabcd2f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,7 @@ Changelog Version 0.5.2 (TBD) ----------------- * Add support for Replica Sets (Thanks @r4fek) +* PyMongo 3 support Version 0.5.1 (Nov 2013) diff --git a/django_mongodb_engine/base.py b/django_mongodb_engine/base.py index 033008e4..827e2a60 100644 --- a/django_mongodb_engine/base.py +++ b/django_mongodb_engine/base.py @@ -248,12 +248,8 @@ def pop(name, default=None): conn_options = dict( host=host, port=int(port), - max_pool_size=None, document_class=dict, tz_aware=False, - _connect=True, - auto_start_request=True, - safe=False ) conn_options.update(options) diff --git a/docs/source/reference/settings.rst b/docs/source/reference/settings.rst index e23ca372..b75bce1e 100644 --- a/docs/source/reference/settings.rst +++ b/docs/source/reference/settings.rst @@ -29,12 +29,13 @@ MongoDB Engine does is lower-casing the names before passing the flags to .. _operations-setting: -Safe Operations (``getLastError``) ----------------------------------- +Acknowledged Operations +----------------------- Use the ``OPERATIONS`` dict to specify extra flags passed to :meth:`Collection.save `, :meth:`~pymongo.collection.Collection.update` or -:meth:`~pymongo.collection.Collection.remove` (and thus to ``getLastError``): +:meth:`~pymongo.collection.Collection.remove` (and thus included in the +write concern): .. code-block:: python @@ -43,19 +44,13 @@ Use the ``OPERATIONS`` dict to specify extra flags passed to ... } -Since any options to ``getLastError`` imply ``safe=True``, -this configuration passes ``safe=True, w=3`` as keyword arguments to each of -:meth:`~pymongo.collection.Collection.save`, -:meth:`~pymongo.collection.Collection.update` and -:meth:`~pymongo.collection.Collection.remove`. - Get a more fine-grained setup by introducing another layer to this dict: .. code-block:: python 'OPTIONS' : { 'OPERATIONS' : { - 'save' : {'safe' : True}, + 'save' : {'w': 3}, 'update' : {}, 'delete' : {'fsync' : True} }, From b2d988f6da473317067a4448c7121a76aaa42ab4 Mon Sep 17 00:00:00 2001 From: "A. Jesse Jiryu Davis" Date: Thu, 16 Apr 2015 09:46:21 -0400 Subject: [PATCH 2/7] PyMongo 3 compatibility in tests. Issue #207. --- tests/mongodb/tests.py | 16 +++++++--------- tests/settings/settings_base.py | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/tests/mongodb/tests.py b/tests/mongodb/tests.py index 715ec5bc..f2297e5d 100644 --- a/tests/mongodb/tests.py +++ b/tests/mongodb/tests.py @@ -248,20 +248,18 @@ def test_setup(flags, **method_kwargs): self.assertEqual(method_kwargs[name], Collection._method_kwargs[name]) - if Collection._method_kwargs['update'].get('safe'): - self.assertEqual(*update_count) + self.assertEqual(*update_count) test_setup({}, save={}, update={'multi': True}, remove={}) + test_setup({}, + save={}, + update={'multi': True}, + remove={}) test_setup({ - 'safe': True}, - save={'safe': True}, - update={'safe': True, 'multi': True}, - remove={'safe': True}) - test_setup({ - 'delete': {'safe': True}, 'update': {}}, + 'delete': {}, 'update': {}}, save={}, update={'multi': True}, - remove={'safe': True}) + remove={}) test_setup({ 'insert': {'fsync': True}, 'delete': {'fsync': True}}, save={}, diff --git a/tests/settings/settings_base.py b/tests/settings/settings_base.py index f6c1b4ef..3482d484 100644 --- a/tests/settings/settings_base.py +++ b/tests/settings/settings_base.py @@ -2,7 +2,7 @@ 'default': { 'ENGINE': 'django_mongodb_engine', 'NAME': 'test', - 'OPTIONS': {'OPERATIONS': {'safe': True}}, + 'OPTIONS': {'OPERATIONS': {}}, }, 'other': { 'ENGINE': 'django_mongodb_engine', From 611aa5abf8e74de5e654388d390046d68431b846 Mon Sep 17 00:00:00 2001 From: "A. Jesse Jiryu Davis" Date: Mon, 4 May 2015 22:37:10 -0400 Subject: [PATCH 3/7] PyMongo 3-compatible find() The "fields" parameter is renamed "projection" in PyMongo 3, but its position is the same. --- django_mongodb_engine/compiler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/django_mongodb_engine/compiler.py b/django_mongodb_engine/compiler.py index a26c0af1..aac1c596 100644 --- a/django_mongodb_engine/compiler.py +++ b/django_mongodb_engine/compiler.py @@ -136,7 +136,7 @@ def get_cursor(self): return [] fields = get_selected_fields(self.query) - cursor = self.collection.find(self.mongo_query, fields=fields) + cursor = self.collection.find(self.mongo_query, fields) if self.ordering: cursor.sort(self.ordering) if self.query.low_mark > 0: From 183d758eb834291149a810de1888cfa5b52c601e Mon Sep 17 00:00:00 2001 From: "A. Jesse Jiryu Davis" Date: Mon, 4 May 2015 22:39:19 -0400 Subject: [PATCH 4/7] PyMongo 3: slave_okay / slaveok is gone. --- django_mongodb_engine/base.py | 4 +++- django_mongodb_engine/utils.py | 2 -- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/django_mongodb_engine/base.py b/django_mongodb_engine/base.py index 827e2a60..4169deca 100644 --- a/django_mongodb_engine/base.py +++ b/django_mongodb_engine/base.py @@ -234,7 +234,9 @@ def pop(name, default=None): replicaset = options.get('replicaset') if not read_preference: - read_preference = options.get('slave_okay', options.get('slaveok')) + read_preference = options.pop('slave_okay', + options.pop('slaveok', None)) + if read_preference: options['read_preference'] = ReadPreference.SECONDARY warnings.warn("slave_okay has been deprecated. " diff --git a/django_mongodb_engine/utils.py b/django_mongodb_engine/utils.py index 6974936b..77aa120e 100644 --- a/django_mongodb_engine/utils.py +++ b/django_mongodb_engine/utils.py @@ -70,8 +70,6 @@ def log(self, op, duration, args, kwargs=None): logger.debug(msg, extra={'duration': duration}) def find(self, *args, **kwargs): - if not 'slave_okay' in kwargs and self.collection.slave_okay: - kwargs['slave_okay'] = True return DebugCursor(self, self.collection, *args, **kwargs) def logging_wrapper(method): From 54882a22ea9a3b5fc90d14d8de222ad8fd11683b Mon Sep 17 00:00:00 2001 From: "A. Jesse Jiryu Davis" Date: Mon, 4 May 2015 22:39:30 -0400 Subject: [PATCH 5/7] PyMongo 3 compatibility in tests.py --- tests/mongodb/tests.py | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/tests/mongodb/tests.py b/tests/mongodb/tests.py index f2297e5d..a8e4b19f 100644 --- a/tests/mongodb/tests.py +++ b/tests/mongodb/tests.py @@ -8,7 +8,10 @@ from django.db.models import Q from gridfs import GridOut -from pymongo import ASCENDING, DESCENDING +from pymongo import (ASCENDING, + DESCENDING, + ReadPreference, + version_tuple as pymongo_version) from django_mongodb_engine.base import DatabaseWrapper @@ -193,7 +196,7 @@ def __enter__(self): return self.new_wrapper def __exit__(self, *exc_info): - self.new_wrapper.connection.disconnect() + self.new_wrapper.connection.close() connections._connections.default = self._old_connection def test_pymongo_connection_args(self): @@ -203,20 +206,23 @@ class foodict(dict): with self.custom_database_wrapper({ 'OPTIONS': { - 'SLAVE_OKAY': True, + 'READ_PREFERENCE': ReadPreference.SECONDARY, 'TZ_AWARE': True, 'DOCUMENT_CLASS': foodict, - }}) as connection: - for name, value in connection.settings_dict[ - 'OPTIONS'].iteritems(): - name = '_Connection__%s' % name.lower() - if name not in connection.connection.__dict__: - # slave_okay was moved into BaseObject in PyMongo 2.0. - name = name.replace('Connection', 'BaseObject') - if name not in connection.connection.__dict__: - # document_class was moved into MongoClient in PyMongo 2.4. - name = name.replace('BaseObject', 'MongoClient') - self.assertEqual(connection.connection.__dict__[name], value) + }}) as db: + connection = db.connection + if pymongo_version[0] >= 3: + tz_aware = connection.codec_options.tz_aware + document_class = connection.codec_options.document_class + else: + tz_aware = connection.tz_aware + document_class = connection.document_class + + self.assertEqual(ReadPreference.SECONDARY, + connection.read_preference) + + self.assertEqual(True, tz_aware) + self.assertEqual(foodict, document_class) def test_operation_flags(self): def test_setup(flags, **method_kwargs): From c20409b2c7990875fc1914b952f9096c2c3bd9da Mon Sep 17 00:00:00 2001 From: "A. Jesse Jiryu Davis" Date: Mon, 4 May 2015 22:40:08 -0400 Subject: [PATCH 6/7] MongoDB 3.0 validates geo2d index range --- tests/mongodb/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mongodb/models.py b/tests/mongodb/models.py index b5bd39c3..f3af8bd0 100644 --- a/tests/mongodb/models.py +++ b/tests/mongodb/models.py @@ -92,7 +92,7 @@ class MongoMeta: {'fields': [('custom_column', -1), 'f3']}, [('geo', '2d')], {'fields': [('geo_custom_column', '2d'), 'f2'], - 'min': 42, 'max': 21}, + 'min': 21, 'max': 42}, {'fields': [('dict1.foo', 1)]}, {'fields': [('dict_custom_column.foo', 1)]}, {'fields': [('embedded.a', 1)]}, From 0805ba9a5cba8b77b28c7e5ecea99fe3950363b5 Mon Sep 17 00:00:00 2001 From: "A. Jesse Jiryu Davis" Date: Mon, 4 May 2015 22:42:36 -0400 Subject: [PATCH 7/7] Update settings.rst for modern PyMongo "Connection" is renamed "MongoClient", "slave_okay" is gone, "network_timeout" is renamed "socketTimeoutMS", and "fsync" is deprecated in recent MongoDB versions. The doc is now equally for PyMongo 2 and 3. --- docs/source/reference/settings.rst | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/docs/source/reference/settings.rst b/docs/source/reference/settings.rst index b75bce1e..97556f2e 100644 --- a/docs/source/reference/settings.rst +++ b/docs/source/reference/settings.rst @@ -3,9 +3,9 @@ Settings .. TODO fix highlighting -Connection Settings -------------------- -Additional flags may be passed to :class:`pymongo.Connection` using the +Client Settings +--------------- +Additional flags may be passed to :class:`pymongo.MongoClient` using the ``OPTIONS`` dictionary:: DATABASES = { @@ -14,9 +14,7 @@ Additional flags may be passed to :class:`pymongo.Connection` using the 'NAME' : 'my_database', ... 'OPTIONS' : { - 'slave_okay' : True, - 'tz_aware' : True, - 'network_timeout' : 42, + 'socketTimeoutMS' : 500, ... } } @@ -24,8 +22,8 @@ Additional flags may be passed to :class:`pymongo.Connection` using the All of these settings directly mirror PyMongo settings. In fact, all Django MongoDB Engine does is lower-casing the names before passing the flags to -:class:`~pymongo.Connection`. For a list of possible options head over to the -`PyMongo documentation on connection options`_. +:class:`~pymongo.MongoClient`. For a list of possible options head over to the +`PyMongo documentation on client options`_. .. _operations-setting: @@ -52,7 +50,7 @@ Get a more fine-grained setup by introducing another layer to this dict: 'OPERATIONS' : { 'save' : {'w': 3}, 'update' : {}, - 'delete' : {'fsync' : True} + 'delete' : {'j' : True} }, ... } @@ -64,10 +62,10 @@ Get a more fine-grained setup by introducing another layer to this dict: "`insert vs. update`" into `save`. -A full list of ``getLastError`` flags may be found in the -`MongoDB documentation `_. +A full list of write concern flags may be found in the +`MongoDB documentation `_. .. _Similar to Django's built-in backends: http://docs.djangoproject.com/en/dev/ref/settings/#std:setting-OPTIONS -.. _PyMongo documentation on connection options: - http://api.mongodb.org/python/current/api/pymongo/connection.html +.. _PyMongo documentation on client options: + http://api.mongodb.org/python/current/api/pymongo/mongo_client.html