Skip to content

PyMongo 3 compatibility. #208

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 3 additions & 5 deletions django_mongodb_engine/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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. "
Expand All @@ -248,12 +250,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)

Expand Down
2 changes: 1 addition & 1 deletion django_mongodb_engine/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 0 additions & 2 deletions django_mongodb_engine/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
39 changes: 16 additions & 23 deletions docs/source/reference/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -14,27 +14,26 @@ 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,
...
}
}
}

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:

Safe Operations (``getLastError``)
----------------------------------
Acknowledged Operations
-----------------------
Use the ``OPERATIONS`` dict to specify extra flags passed to
:meth:`Collection.save <pymongo.collection.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

Expand All @@ -43,21 +42,15 @@ 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}
'delete' : {'j' : True}
},
...
}
Expand All @@ -69,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 <http://www.mongodb.org/display/DOCS/getLastError+Command>`_.
A full list of write concern flags may be found in the
`MongoDB documentation <http://docs.mongodb.org/manual/core/write-concern/>`_.

.. _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
2 changes: 1 addition & 1 deletion tests/mongodb/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)]},
Expand Down
50 changes: 27 additions & 23 deletions tests/mongodb/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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):
Expand All @@ -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):
Expand Down Expand Up @@ -248,20 +254,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={},
Expand Down
2 changes: 1 addition & 1 deletion tests/settings/settings_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
'default': {
'ENGINE': 'django_mongodb_engine',
'NAME': 'test',
'OPTIONS': {'OPERATIONS': {'safe': True}},
'OPTIONS': {'OPERATIONS': {}},
},
'other': {
'ENGINE': 'django_mongodb_engine',
Expand Down