Updated for pymongo
This commit is contained in:
parent
69989365c7
commit
3da37fbf6e
@ -12,7 +12,7 @@ __all__ = (document.__all__ + fields.__all__ + connection.__all__ +
|
||||
|
||||
__author__ = 'Harry Marr'
|
||||
|
||||
VERSION = (0, 4, 0)
|
||||
VERSION = (0, 4, 1)
|
||||
|
||||
def get_version():
|
||||
version = '%s.%s' % (VERSION[0], VERSION[1])
|
||||
|
@ -2,8 +2,8 @@ from queryset import QuerySet, QuerySetManager
|
||||
from queryset import DoesNotExist, MultipleObjectsReturned
|
||||
|
||||
import sys
|
||||
import bson
|
||||
import pymongo
|
||||
import pymongo.objectid
|
||||
|
||||
|
||||
_document_registry = {}
|
||||
@ -111,9 +111,9 @@ class ObjectIdField(BaseField):
|
||||
# return unicode(value)
|
||||
|
||||
def to_mongo(self, value):
|
||||
if not isinstance(value, pymongo.objectid.ObjectId):
|
||||
if not isinstance(value, bson.objectid.ObjectId):
|
||||
try:
|
||||
return pymongo.objectid.ObjectId(unicode(value))
|
||||
return bson.objectid.ObjectId(unicode(value))
|
||||
except Exception, e:
|
||||
#e.message attribute has been deprecated since Python 2.6
|
||||
raise ValidationError(unicode(e))
|
||||
@ -124,7 +124,7 @@ class ObjectIdField(BaseField):
|
||||
|
||||
def validate(self, value):
|
||||
try:
|
||||
pymongo.objectid.ObjectId(unicode(value))
|
||||
bson.objectid.ObjectId(unicode(value))
|
||||
except:
|
||||
raise ValidationError('Invalid Object ID')
|
||||
|
||||
|
@ -124,7 +124,7 @@ class MapReduceDocument(object):
|
||||
|
||||
:param collection: An instance of :class:`~pymongo.Collection`
|
||||
:param key: Document/result key, often an instance of
|
||||
:class:`~pymongo.objectid.ObjectId`. If supplied as
|
||||
:class:`~bson.objectid.ObjectId`. If supplied as
|
||||
an ``ObjectId`` found in the given ``collection``,
|
||||
the object can be accessed via the ``object`` property.
|
||||
:param value: The result(s) for this key.
|
||||
|
@ -5,9 +5,9 @@ from operator import itemgetter
|
||||
|
||||
import re
|
||||
import pymongo
|
||||
import pymongo.dbref
|
||||
import pymongo.son
|
||||
import pymongo.binary
|
||||
import bson.dbref
|
||||
import bson.son
|
||||
import bson.binary
|
||||
import datetime
|
||||
import decimal
|
||||
import gridfs
|
||||
@ -306,7 +306,7 @@ class ListField(BaseField):
|
||||
deref_list = []
|
||||
for value in value_list:
|
||||
# Dereference DBRefs
|
||||
if isinstance(value, (pymongo.dbref.DBRef)):
|
||||
if isinstance(value, (bson.dbref.DBRef)):
|
||||
value = _get_db().dereference(value)
|
||||
deref_list.append(referenced_type._from_son(value))
|
||||
else:
|
||||
@ -319,7 +319,7 @@ class ListField(BaseField):
|
||||
deref_list = []
|
||||
for value in value_list:
|
||||
# Dereference DBRefs
|
||||
if isinstance(value, (dict, pymongo.son.SON)):
|
||||
if isinstance(value, (dict, bson.son.SON)):
|
||||
deref_list.append(self.field.dereference(value))
|
||||
else:
|
||||
deref_list.append(value)
|
||||
@ -444,7 +444,7 @@ class ReferenceField(BaseField):
|
||||
# Get value from document instance if available
|
||||
value = instance._data.get(self.name)
|
||||
# Dereference DBRefs
|
||||
if isinstance(value, (pymongo.dbref.DBRef)):
|
||||
if isinstance(value, (bson.dbref.DBRef)):
|
||||
value = _get_db().dereference(value)
|
||||
if value is not None:
|
||||
instance._data[self.name] = self.document_type._from_son(value)
|
||||
@ -466,13 +466,13 @@ class ReferenceField(BaseField):
|
||||
|
||||
id_ = id_field.to_mongo(id_)
|
||||
collection = self.document_type._meta['collection']
|
||||
return pymongo.dbref.DBRef(collection, id_)
|
||||
return bson.dbref.DBRef(collection, id_)
|
||||
|
||||
def prepare_query_value(self, op, value):
|
||||
return self.to_mongo(value)
|
||||
|
||||
def validate(self, value):
|
||||
assert isinstance(value, (self.document_type, pymongo.dbref.DBRef))
|
||||
assert isinstance(value, (self.document_type, bson.dbref.DBRef))
|
||||
|
||||
def lookup_member(self, member_name):
|
||||
return self.document_type._fields.get(member_name)
|
||||
@ -490,7 +490,7 @@ class GenericReferenceField(BaseField):
|
||||
return self
|
||||
|
||||
value = instance._data.get(self.name)
|
||||
if isinstance(value, (dict, pymongo.son.SON)):
|
||||
if isinstance(value, (dict, bson.son.SON)):
|
||||
instance._data[self.name] = self.dereference(value)
|
||||
|
||||
return super(GenericReferenceField, self).__get__(instance, owner)
|
||||
@ -518,7 +518,7 @@ class GenericReferenceField(BaseField):
|
||||
|
||||
id_ = id_field.to_mongo(id_)
|
||||
collection = document._meta['collection']
|
||||
ref = pymongo.dbref.DBRef(collection, id_)
|
||||
ref = bson.dbref.DBRef(collection, id_)
|
||||
return {'_cls': document.__class__.__name__, '_ref': ref}
|
||||
|
||||
def prepare_query_value(self, op, value):
|
||||
@ -534,7 +534,7 @@ class BinaryField(BaseField):
|
||||
super(BinaryField, self).__init__(**kwargs)
|
||||
|
||||
def to_mongo(self, value):
|
||||
return pymongo.binary.Binary(value)
|
||||
return bson.binary.Binary(value)
|
||||
|
||||
def to_python(self, value):
|
||||
# Returns str not unicode as this is binary data
|
||||
@ -680,7 +680,7 @@ class FileField(BaseField):
|
||||
def validate(self, value):
|
||||
if value.grid_id is not None:
|
||||
assert isinstance(value, GridFSProxy)
|
||||
assert isinstance(value.grid_id, pymongo.objectid.ObjectId)
|
||||
assert isinstance(value.grid_id, bson.objectid.ObjectId)
|
||||
|
||||
|
||||
class GeoPointField(BaseField):
|
||||
|
@ -2,9 +2,9 @@ from connection import _get_db
|
||||
|
||||
import pprint
|
||||
import pymongo
|
||||
import pymongo.code
|
||||
import pymongo.dbref
|
||||
import pymongo.objectid
|
||||
import bson.code
|
||||
import bson.dbref
|
||||
import bson.objectid
|
||||
import re
|
||||
import copy
|
||||
import itertools
|
||||
@ -667,8 +667,8 @@ class QuerySet(object):
|
||||
def __len__(self):
|
||||
return self.count()
|
||||
|
||||
def map_reduce(self, map_f, reduce_f, finalize_f=None, limit=None,
|
||||
scope=None, keep_temp=False):
|
||||
def map_reduce(self, map_f, reduce_f, output, finalize_f=None, limit=None,
|
||||
scope=None):
|
||||
"""Perform a map/reduce query using the current query spec
|
||||
and ordering. While ``map_reduce`` respects ``QuerySet`` chaining,
|
||||
it must be the last call made, as it does not return a maleable
|
||||
@ -678,52 +678,61 @@ class QuerySet(object):
|
||||
and :meth:`~mongoengine.tests.QuerySetTest.test_map_advanced`
|
||||
tests in ``tests.queryset.QuerySetTest`` for usage examples.
|
||||
|
||||
:param map_f: map function, as :class:`~pymongo.code.Code` or string
|
||||
:param map_f: map function, as :class:`~bson.code.Code` or string
|
||||
:param reduce_f: reduce function, as
|
||||
:class:`~pymongo.code.Code` or string
|
||||
:class:`~bson.code.Code` or string
|
||||
:param output: output collection name, if set to 'inline' will try to
|
||||
use :class:`~pymongo.collection.Collection.inline_map_reduce`
|
||||
This can also be a dictionary containing output options
|
||||
see: http://docs.mongodb.org/manual/reference/commands/#mapReduce
|
||||
:param finalize_f: finalize function, an optional function that
|
||||
performs any post-reduction processing.
|
||||
:param scope: values to insert into map/reduce global scope. Optional.
|
||||
:param limit: number of objects from current query to provide
|
||||
to map/reduce method
|
||||
:param keep_temp: keep temporary table (boolean, default ``True``)
|
||||
|
||||
Returns an iterator yielding
|
||||
:class:`~mongoengine.document.MapReduceDocument`.
|
||||
|
||||
.. note:: Map/Reduce requires server version **>= 1.1.1**. The PyMongo
|
||||
.. note::
|
||||
|
||||
Map/Reduce changed in server version **>= 1.7.4**. The PyMongo
|
||||
:meth:`~pymongo.collection.Collection.map_reduce` helper requires
|
||||
PyMongo version **>= 1.2**.
|
||||
PyMongo version **>= 1.11**.
|
||||
|
||||
.. versionchanged:: 0.5
|
||||
- removed ``keep_temp`` keyword argument, which was only relevant
|
||||
for MongoDB server versions older than 1.7.4
|
||||
|
||||
.. versionadded:: 0.3
|
||||
"""
|
||||
from document import MapReduceDocument
|
||||
|
||||
if not hasattr(self._collection, "map_reduce"):
|
||||
raise NotImplementedError("Requires MongoDB >= 1.1.1")
|
||||
raise NotImplementedError("Requires MongoDB >= 1.7.1")
|
||||
|
||||
map_f_scope = {}
|
||||
if isinstance(map_f, pymongo.code.Code):
|
||||
if isinstance(map_f, bson.code.Code):
|
||||
map_f_scope = map_f.scope
|
||||
map_f = unicode(map_f)
|
||||
map_f = pymongo.code.Code(self._sub_js_fields(map_f), map_f_scope)
|
||||
map_f = bson.code.Code(self._sub_js_fields(map_f), map_f_scope)
|
||||
|
||||
reduce_f_scope = {}
|
||||
if isinstance(reduce_f, pymongo.code.Code):
|
||||
if isinstance(reduce_f, bson.code.Code):
|
||||
reduce_f_scope = reduce_f.scope
|
||||
reduce_f = unicode(reduce_f)
|
||||
reduce_f_code = self._sub_js_fields(reduce_f)
|
||||
reduce_f = pymongo.code.Code(reduce_f_code, reduce_f_scope)
|
||||
reduce_f = bson.code.Code(reduce_f_code, reduce_f_scope)
|
||||
|
||||
mr_args = {'query': self._query, 'keeptemp': keep_temp}
|
||||
mr_args = {'query': self._query}
|
||||
|
||||
if finalize_f:
|
||||
finalize_f_scope = {}
|
||||
if isinstance(finalize_f, pymongo.code.Code):
|
||||
if isinstance(finalize_f, bson.code.Code):
|
||||
finalize_f_scope = finalize_f.scope
|
||||
finalize_f = unicode(finalize_f)
|
||||
finalize_f_code = self._sub_js_fields(finalize_f)
|
||||
finalize_f = pymongo.code.Code(finalize_f_code, finalize_f_scope)
|
||||
finalize_f = bson.code.Code(finalize_f_code, finalize_f_scope)
|
||||
mr_args['finalize'] = finalize_f
|
||||
|
||||
if scope:
|
||||
@ -732,7 +741,15 @@ class QuerySet(object):
|
||||
if limit:
|
||||
mr_args['limit'] = limit
|
||||
|
||||
results = self._collection.map_reduce(map_f, reduce_f, **mr_args)
|
||||
if output == 'inline' and not self._ordering:
|
||||
map_reduce_function = 'inline_map_reduce'
|
||||
else:
|
||||
map_reduce_function = 'map_reduce'
|
||||
mr_args['out'] = output
|
||||
|
||||
results = getattr(self._collection, map_reduce_function)(map_f, reduce_f, **mr_args)
|
||||
|
||||
if map_reduce_function == 'map_reduce':
|
||||
results = results.find()
|
||||
|
||||
if self._ordering:
|
||||
@ -1037,7 +1054,7 @@ class QuerySet(object):
|
||||
query['$where'] = self._where_clause
|
||||
|
||||
scope['query'] = query
|
||||
code = pymongo.code.Code(code, scope=scope)
|
||||
code = bson.code.Code(code, scope=scope)
|
||||
|
||||
db = _get_db()
|
||||
return db.eval(code, *fields)
|
||||
|
@ -1,5 +1,6 @@
|
||||
import unittest
|
||||
from datetime import datetime
|
||||
import bson
|
||||
import pymongo
|
||||
|
||||
from mongoengine import *
|
||||
@ -611,7 +612,7 @@ class DocumentTest(unittest.TestCase):
|
||||
|
||||
# Test laziness
|
||||
self.assertTrue(isinstance(post_obj._data['author'],
|
||||
pymongo.dbref.DBRef))
|
||||
bson.dbref.DBRef))
|
||||
self.assertTrue(isinstance(post_obj.author, self.Person))
|
||||
self.assertEqual(post_obj.author.name, 'Test User')
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
import unittest
|
||||
import pymongo
|
||||
import bson
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from mongoengine.queryset import (QuerySet, MultipleObjectsReturned,
|
||||
@ -58,7 +59,7 @@ class QuerySetTest(unittest.TestCase):
|
||||
self.assertEqual(len(people), 2)
|
||||
results = list(people)
|
||||
self.assertTrue(isinstance(results[0], self.Person))
|
||||
self.assertTrue(isinstance(results[0].id, (pymongo.objectid.ObjectId,
|
||||
self.assertTrue(isinstance(results[0].id, (bson.objectid.ObjectId,
|
||||
str, unicode)))
|
||||
self.assertEqual(results[0].name, "User A")
|
||||
self.assertEqual(results[0].age, 20)
|
||||
@ -802,7 +803,7 @@ class QuerySetTest(unittest.TestCase):
|
||||
"""
|
||||
|
||||
# run a map/reduce operation spanning all posts
|
||||
results = BlogPost.objects.map_reduce(map_f, reduce_f)
|
||||
results = BlogPost.objects.map_reduce(map_f, reduce_f, "myresults")
|
||||
results = list(results)
|
||||
self.assertEqual(len(results), 4)
|
||||
|
||||
@ -851,7 +852,7 @@ class QuerySetTest(unittest.TestCase):
|
||||
}
|
||||
"""
|
||||
|
||||
results = BlogPost.objects.map_reduce(map_f, reduce_f)
|
||||
results = BlogPost.objects.map_reduce(map_f, reduce_f, "myresults")
|
||||
results = list(results)
|
||||
|
||||
self.assertEqual(results[0].object, post1)
|
||||
@ -962,6 +963,7 @@ class QuerySetTest(unittest.TestCase):
|
||||
results = Link.objects.order_by("-value")
|
||||
results = results.map_reduce(map_f,
|
||||
reduce_f,
|
||||
"myresults",
|
||||
finalize_f=finalize_f,
|
||||
scope=scope)
|
||||
results = list(results)
|
||||
|
Loading…
x
Reference in New Issue
Block a user