Пример #1
0
    def group(self, key, condition, initial, reduce, callback, finalize=None,
              command=True):
        """Perform a query similar to an SQL *group by* operation.

        Returns an array of grouped items.

        The `key` parameter can be:

          - ``None`` to use the entire document as a key.
          - A :class:`list` of keys (each a :class:`basestring`) to group by.
          - A :class:`basestring` or :class:`~bson.code.Code` instance
            containing a JavaScript function to be applied to each
            document, returning the key to group by.

        :Parameters:
          - `key`: fields to group by (see above description)
          - `condition`: specification of rows to be
            considered (as a :meth:`find` query specification)
          - `initial`: initial value of the aggregation counter object
          - `reduce`: aggregation function as a JavaScript string
          - `finalize`: function to be called on each object in output list.
          - `command` (optional): DEPRECATED if ``True``, run the group as a
            command instead of in an eval - this option is deprecated and
            will be removed in favor of running all groups as commands

        .. versionchanged:: 1.4
           The `key` argument can now be ``None`` or a JavaScript function,
           in addition to a :class:`list` of keys.
        .. versionchanged:: 1.3
           The `command` argument now defaults to ``True`` and is deprecated.
        """
        if not command:
            warnings.warn("eval-based groups are deprecated, and the "
                          "command option will be removed.",
                          DeprecationWarning)

        group = {}
        if isinstance(key, basestring):
            group["$keyf"] = Code(key)
        elif key is not None:
            group = {"key": helpers._fields_list_to_dict(key)}
        group["ns"] = self.__name
        group["$reduce"] = Code(reduce)
        group["cond"] = condition
        group["initial"] = initial
        if finalize is not None:
            group["finalize"] = Code(finalize)

        def mod_callback(resp):
            callback(resp["retval"])
        
        self.__database.command("group", callback=mod_callback, value = group)
Пример #2
0
    def command(self, command, value=1,
                callback=None, check=True, allowable_errors=[],
                uuid_subtype=OLD_UUID_SUBTYPE, **kwargs):
        """Issue a MongoDB command.

        Send command `command` to the database and return the
        response. If `command` is an instance of :class:`basestring`
        (:class:`str` in python 3) then the command {`command`: `value`}
        will be sent. Otherwise, `command` must be an instance of
        :class:`dict` and will be sent as is.

        Command responses will be passed to callback.

        Any additional keyword arguments will be added to the final
        command document before it is sent.

        For example, a command like ``{buildinfo: 1}`` can be sent
        using:

        >>> db.command("buildinfo")

        For a command where the value matters, like ``{collstats:
        collection_name}`` we can do:

        >>> db.command("collstats", collection_name)

        For commands that take additional arguments we can use
        kwargs. So ``{filemd5: object_id, root: file_root}`` becomes:

        >>> db.command("filemd5", object_id, root=file_root)

        :Parameters:
          - `command`: document representing the command to be issued,
            or the name of the command (for simple commands only).

            .. note:: the order of keys in the `command` document is
               significant (the "verb" must come first), so commands
               which require multiple keys (e.g. `findandmodify`)
               should use an instance of :class:`~bson.son.SON` or
               a string and kwargs instead of a Python `dict`.

          - `value` (optional): value to use for the command verb when
            `command` is passed as a string
          - `check` (optional): check the response for errors, raising
            :class:`~pymongo.errors.OperationFailure` if there are any
          - `allowable_errors`: if `check` is ``True``, error messages
            in this list will be ignored by error-checking
          - `uuid_subtype` (optional): The BSON binary subtype to use
            for a UUID used in this command.
          - `**kwargs` (optional): additional keyword arguments will
            be added to the command document before it is sent

        .. versionchanged:: 2.1.1+
           Added support for `as_class` - the class you want to use for
           the resulting documents
        .. versionchanged:: 1.6
           Added the `value` argument for string commands, and keyword
           arguments for additional command options.
        .. versionchanged:: 1.5
           `command` can be a string in addition to a full document.
        .. versionadded:: 1.4

        .. mongodoc:: commands
        """

        if isinstance(command, basestring):
            command = SON([(command, value)])

        extra_opts = {
            'as_class': kwargs.pop('as_class', None),
            'read_preference': kwargs.pop('read_preference',
                                          self.read_preference),
            'slave_okay': kwargs.pop('slave_okay', self.slave_okay),
            '_must_use_master': kwargs.pop('_use_master', True),
            '_is_command': True,
            '_uuid_subtype': uuid_subtype
        }

        fields = kwargs.get('fields')
        if fields is not None and not isinstance(fields, dict):
            kwargs['fields'] = helpers._fields_list_to_dict(fields)

        command.update(kwargs)

        if callback:
            def mod_callback(result):
                 if not isinstance(result, Exception):
                     if check:
                         msg = "command %s failed: %%s" % repr(command).replace("%", "%%")
                         helpers._check_command_response(result, self.connection.disconnect,
                                            msg, allowable_errors)
                  
                     callback(result)
                 else:
                     callback(result)
                     
        else:       
            mod_callback = None
            
        self["$cmd"].find_one(spec_or_id = command, callback=mod_callback, **extra_opts)
Пример #3
0
    def __init__(self, collection, 
                 callback = None, 
                 processor = None, 
                 spec=None, 
                 fields=None, 
                 skip=0, 
                 limit=0,
                 timeout=True, 
                 snapshot=False, 
                 tailable=False, 
                 sort=None,
                 max_scan=None, 
                 as_class=None,
                 store = True,
                 _must_use_master=False, 
                 _is_command=False,
                 **kwargs):
        """Create a new cursor.

        Should not be called directly by application developers - see
        :meth:`~pymongo.collection.Collection.find` instead.

        .. mongodoc:: cursors
        """
        self.__id = None

        self.__error = None

        if spec is None:
            spec = {}

        if not isinstance(spec, dict):
            raise TypeError("spec must be an instance of dict")
        if not isinstance(skip, int):
            raise TypeError("skip must be an instance of int")
        if not isinstance(limit, int):
            raise TypeError("limit must be an instance of int")
        if not isinstance(timeout, bool):
            raise TypeError("timeout must be an instance of bool")
        if not isinstance(snapshot, bool):
            raise TypeError("snapshot must be an instance of bool")
        if not isinstance(tailable, bool):
            raise TypeError("tailable must be an instance of bool")

        if fields is not None:
            if not fields:
                fields = {"_id": 1}
            if not isinstance(fields, dict):
                fields = helpers._fields_list_to_dict(fields)

        if as_class is None:
            as_class = collection.database.connection.document_class

        self.__collection = collection
        self.__callback = callback
        self.__processor = processor
        self.__spec = spec
        self.__fields = fields
        self.__skip = skip
        self.__limit = limit
        self.__batch_size = 0
        self.__store = store

        self.__empty = False

        self.__timeout = timeout
        self.__tailable = tailable
        self.__snapshot = snapshot
        self.__ordering = sort and helpers._index_document(sort) or None
        self.__max_scan = max_scan
        self.__explain = False
        self.__hint = None
        self.__as_class = as_class
        self.__tz_aware = collection.database.connection.tz_aware
        self.__must_use_master = _must_use_master
        self.__is_command = _is_command

        self.__data = []
        self.__datastore = []
        self.__connection_id = None
        self.__retrieved = 0
        self.__killed = False

        # this is for passing network_timeout through if it's specified
        # need to use kwargs as None is a legit value for network_timeout
        self.__kwargs = kwargs
Пример #4
0
    def __init__(self,
                 collection,
                 callback=None,
                 processor=None,
                 spec=None,
                 fields=None,
                 skip=0,
                 limit=0,
                 timeout=True,
                 snapshot=False,
                 tailable=False,
                 sort=None,
                 max_scan=None,
                 as_class=None,
                 store=True,
                 _must_use_master=False,
                 _is_command=False,
                 **kwargs):
        """Create a new cursor.

        Should not be called directly by application developers - see
        :meth:`~pymongo.collection.Collection.find` instead.

        .. mongodoc:: cursors
        """
        self.__id = None

        self.__error = None

        if spec is None:
            spec = {}

        if not isinstance(spec, dict):
            raise TypeError("spec must be an instance of dict")
        if not isinstance(skip, int):
            raise TypeError("skip must be an instance of int")
        if not isinstance(limit, int):
            raise TypeError("limit must be an instance of int")
        if not isinstance(timeout, bool):
            raise TypeError("timeout must be an instance of bool")
        if not isinstance(snapshot, bool):
            raise TypeError("snapshot must be an instance of bool")
        if not isinstance(tailable, bool):
            raise TypeError("tailable must be an instance of bool")

        if fields is not None:
            if not fields:
                fields = {"_id": 1}
            if not isinstance(fields, dict):
                fields = helpers._fields_list_to_dict(fields)

        if as_class is None:
            as_class = collection.database.connection.document_class

        self.__collection = collection
        self.__callback = callback
        self.__processor = processor
        self.__spec = spec
        self.__fields = fields
        self.__skip = skip
        self.__limit = limit
        self.__batch_size = 0
        self.__store = store

        self.__empty = False

        self.__timeout = timeout
        self.__tailable = tailable
        self.__snapshot = snapshot
        self.__ordering = sort and helpers._index_document(sort) or None
        self.__max_scan = max_scan
        self.__explain = False
        self.__hint = None
        self.__as_class = as_class
        self.__tz_aware = collection.database.connection.tz_aware
        self.__must_use_master = _must_use_master
        self.__is_command = _is_command

        self.__data = []
        self.__datastore = []
        self.__connection_id = None
        self.__retrieved = 0
        self.__killed = False

        # this is for passing network_timeout through if it's specified
        # need to use kwargs as None is a legit value for network_timeout
        self.__kwargs = kwargs
Пример #5
0
 def __init__(self, collection, callback=None, processor=None, spec=None, fields=None, skip=0, limit=0,
              timeout=True, snapshot=False, tailable=False, sort=None,
              max_scan=None, as_class=None, slave_okay=False,
              await_data=False, partial=False, manipulate=True,
              read_preference=ReadPreference.PRIMARY,
              _must_use_master=False, _is_command=False,
              _uuid_subtype=None, **kwargs):
     """Create a new cursor.
     
     Should not be called directly by application developers - see
     :meth:`~pymongo.collection.Collection.find` instead.
     
     .. mongodoc:: cursors
     """
     self.__id = None
     
     self.__error = None
     
     if spec is None:
         spec = {}
     
     if not isinstance(spec, dict):
         raise TypeError("spec must be an instance of dict")
     if not isinstance(skip, int):
         raise TypeError("skip must be an instance of int")
     if not isinstance(limit, int):
         raise TypeError("limit must be an instance of int")
     if not isinstance(timeout, bool):
         raise TypeError("timeout must be an instance of bool")
     if not isinstance(snapshot, bool):
         raise TypeError("snapshot must be an instance of bool")
     if not isinstance(tailable, bool):
         raise TypeError("tailable must be an instance of bool")
     if not isinstance(slave_okay, bool):
         raise TypeError("slave_okay must be an instance of bool")
     if not isinstance(await_data, bool):
         raise TypeError("await_data must be an instance of bool")
     if not isinstance(partial, bool):
         raise TypeError("partial must be an instance of bool")
     
     if fields is not None:
         if not fields:
             fields = {"_id": 1}
         if not isinstance(fields, dict):
             fields = helpers._fields_list_to_dict(fields)
     
     if as_class is None:
         as_class = collection.database.connection.document_class
     
     self.__collection = collection
     self.__callback = callback
     self.__processor = processor
     self.__spec = spec
     self.__fields = fields
     self.__skip = skip
     self.__limit = limit
     self.__batch_size = 0
     # self.__store = True
     
     # This is ugly. People want to be able to do cursor[5:5] and
     # get an empty result set (old behavior was an
     # exception). It's hard to do that right, though, because the
     # server uses limit(0) to mean 'no limit'. So we set __empty
     # in that case and check for it when iterating. We also unset
     # it anytime we change __limit.
     self.__empty = False
     
     self.__timeout = timeout
     self.__tailable = tailable
     self.__await_data = tailable and await_data
     self.__partial = partial
     self.__snapshot = snapshot
     self.__ordering = sort and helpers._index_document(sort) or None
     self.__max_scan = max_scan
     self.__explain = False
     self.__hint = None
     self.__as_class = as_class
     self.__slave_okay = slave_okay
     self.__manipulate = manipulate
     self.__read_preference = read_preference
     self.__tz_aware = collection.database.connection.tz_aware
     self.__must_use_master = _must_use_master
     self.__is_command = _is_command
     self.__uuid_subtype = _uuid_subtype or collection.uuid_subtype
     self.__query_flags = 0
     
     self.__data = []
     self.__datastore = []
     self.__connection_id = None
     self.__retrieved = 0
     self.__killed = False
     
     # this is for passing network_timeout through if it's specified
     # need to use kwargs as None is a legit value for network_timeout
     self.__kwargs = kwargs