Exemplo n.º 1
0
    def __init__(self, retrieved_fields=None, loading_from_db=False, **kwargs):
        ''' :param retrieved_fields: The names of the fields returned when loading \
                a partial object.  This argument should not be explicitly set \
                by subclasses
            :param \*\*kwargs:  The values for all of the fields in the document. \
                Any additional fields will raise a :class:`~mongoalchemy.document.ExtraValueException` and \
                any missing (but required) fields will raise a :class:`~mongoalchemy.document.MissingValueException`. \
                Both types of exceptions are subclasses of :class:`~mongoalchemy.document.DocumentException`.
        '''
        self.partial = retrieved_fields is not None
        self.retrieved_fields = self.__normalize(retrieved_fields)

        # Mapping from attribute names to values.
        self._values = {}
        self.__extra_fields = {}

        cls = self.__class__

        # Process the fields on the object
        fields = self.get_fields()
        for name, field in fields.items():
            # print name
            if self.partial and field.db_field not in self.retrieved_fields:
                self._values[name] = Value(field, self, retrieved=False)
            elif name in kwargs:
                field = getattr(cls, name)
                value = kwargs[name]
                self._values[name] = Value(field,
                                           self,
                                           from_db=loading_from_db)
                field.set_value(self, value)
            elif field.auto:
                self._values[name] = Value(field, self, from_db=False)
            else:
                self._values[name] = Value(field, self, from_db=False)

        # Process any extra fields
        for k in kwargs:
            if k not in fields:
                if self.config_extra_fields == 'ignore':
                    self.__extra_fields[k] = kwargs[k]
                else:
                    raise ExtraValueException(k)

        self.__extra_fields_orig = dict(self.__extra_fields)

        # Validate defult sort
        if self.config_default_sort:
            for (name, direction) in self.config_default_sort:
                try:
                    resolve_name(type(self), name)
                    dirs = (1, -1, pymongo.ASCENDING, pymongo.DESCENDING)
                    if direction not in dirs:
                        m = 'Bad sort direction on %s: %s' % (name, direction)
                        raise BadFieldSpecification(m)
                except FieldNotFoundException:
                    raise BadFieldSpecification("Could not resolve field %s in"
                                                " config_default_sort" % name)
Exemplo n.º 2
0
    def __init__(self, retrieved_fields=None, loading_from_db=False, **kwargs):
        ''' :param retrieved_fields: The names of the fields returned when loading \
                a partial object.  This argument should not be explicitly set \
                by subclasses
            :param \*\*kwargs:  The values for all of the fields in the document. \
                Any additional fields will raise a :class:`~mongoalchemy.document.ExtraValueException` and \ 
                any missing (but required) fields will raise a :class:`~mongoalchemy.document.MissingValueException`. \
                Both types of exceptions are subclasses of :class:`~mongoalchemy.document.DocumentException`.
        '''
        self.partial = retrieved_fields is not None
        self.retrieved_fields = self.__normalize(retrieved_fields)
        
        # Mapping from attribute names to values.
        self._values = {}
        self.__extra_fields = {}
        
        cls = self.__class__
                
        # Process the fields on the object
        fields = self.get_fields()
        for name, field in fields.iteritems():
            # print name
            if self.partial and field.db_field not in self.retrieved_fields:
                self._values[name] = Value(field, self, retrieved=False)
            elif name in kwargs:
                field = getattr(cls, name)
                value = kwargs[name]
                self._values[name] = Value(field, self, 
                                           from_db=loading_from_db)
                getattr(cls, name).set_value(self, kwargs[name])
            elif field.auto:
                self._values[name] = Value(field, self, from_db=False)
            else:
                self._values[name] = Value(field, self, from_db=False)
        
        # Process any extra fields
        for k in kwargs:
            if k not in fields:
                if self.config_extra_fields == 'ignore':
                    self.__extra_fields[k] = kwargs[k]
                else:
                    raise ExtraValueException(k)

        self.__extra_fields_orig = dict(self.__extra_fields)

        # Validate defult sort
        if self.config_default_sort:
            for (name, direction) in self.config_default_sort:
                try:
                    resolve_name(type(self), name)
                    dirs = (1, -1, pymongo.ASCENDING, pymongo.DESCENDING)
                    if direction not in dirs:
                        m = 'Bad sort direction on %s: %s' % (name, direction)
                        raise BadFieldSpecification(m)
                except FieldNotFoundException:
                    raise BadFieldSpecification("Could not resolve field %s in" 
                            " config_default_sort" % name)
Exemplo n.º 3
0
 def __sort(self, qfield, direction):
     qfield = resolve_name(self.type, qfield)
     name = str(qfield)
     for n, _ in self._sort:
         if n == name:
             raise BadQueryException('Already sorting by %s' % name)
     self._sort.append((name, direction))
     return self
Exemplo n.º 4
0
 def __hint(self, qfield, direction):
     qfield = resolve_name(self.type, qfield)
     name = str(qfield)
     for n, _ in self.hints:
         if n == name:
             raise BadQueryException('Already gave hint for %s' % name)
     self.hints.append((name, direction))
     return self
Exemplo n.º 5
0
 def __sort(self, qfield, direction):
     qfield = resolve_name(self.type, qfield)
     name = str(qfield)
     for n, _ in self._sort:
         if n == name:
             raise BadQueryException('Already sorting by %s' % name)
     self._sort.append((name, direction))
     return self
Exemplo n.º 6
0
 def __hint(self, qfield, direction):
     qfield = resolve_name(self.type, qfield)
     name = str(qfield)
     for n, _ in self.hints:
         if n == name:
             raise BadQueryException('Already gave hint for %s' % name)
     self.hints.append((name, direction))
     return self
Exemplo n.º 7
0
    def _atomic_generic_op(self, op, qfield, value):
        qfield = resolve_name(self.query.type, qfield)
        if op not in qfield.valid_modifiers:
            raise InvalidModifierException(qfield, op)

        if op not in self.update_data:
            self.update_data[op] = {}
        self.update_data[op][qfield.get_absolute_name()] = value
        return self
Exemplo n.º 8
0
    def _atomic_generic_op(self, op, qfield, value):
        qfield = resolve_name(self.query.type, qfield)
        if op not in qfield.valid_modifiers:
            raise InvalidModifierException(qfield, op)

        if op not in self.update_data:
            self.update_data[op] = {}
        self.update_data[op][qfield.get_absolute_name()] = value
        return self
Exemplo n.º 9
0
 def _apply_dict(self, qe_dict):
     ''' Apply a query expression, updating the query object '''
     for k, v in qe_dict.iteritems():
         k = resolve_name(self.type, k)
         if not k in self.__query:
             self.__query[k] = v
             continue
         if not isinstance(self.__query[k], dict) or not isinstance(v, dict):
             raise BadQueryException('Multiple assignments to a field must all be dicts.')
         self.__query[k].update(**v)
Exemplo n.º 10
0
 def _atomic_list_op_multivalue(self, op, qfield, *value):
     qfield = resolve_name(self.query.type, qfield)
     if op not in qfield.valid_modifiers:
         raise InvalidModifierException(qfield, op)
     wrapped = []
     for v in value:
         wrapped.append(qfield.get_type().item_type.wrap(v))
     if op not in self.update_data:
         self.update_data[op] = {}
     self.update_data[op][qfield.get_absolute_name()] = value
     return self
Exemplo n.º 11
0
 def _atomic_list_op_multivalue(self, op, qfield, *value):
     qfield = resolve_name(self.query.type, qfield)
     if op not in qfield.valid_modifiers:
         raise InvalidModifierException(qfield, op)
     wrapped = []
     for v in value:
         wrapped.append(qfield.get_type().item_type.wrap(v))
     if op not in self.update_data:
         self.update_data[op] = {}
     self.update_data[op][qfield.get_absolute_name()] = value
     return self
Exemplo n.º 12
0
 def nin(self, qfield, *values):
     ''' Check to see that the value of ``qfield`` is not one of ``values``
         
         :param qfield: Instances of :class:`mongoalchemy.query_expression.QueryExpression`
         :param values: Values should be python values which ``qfield`` \
             understands
     '''
     # TODO: make sure that this field represents a list
     qfield = resolve_name(self.type, qfield)
     self.filter(QueryExpression({ qfield : { '$nin' : [qfield.wrap_value(value) for value in values]}}))
     return self
Exemplo n.º 13
0
 def _apply_dict(self, qe_dict):
     ''' Apply a query expression, updating the query object '''
     for k, v in qe_dict.iteritems():
         k = resolve_name(self.type, k)
         if not k in self.__query:
             self.__query[k] = v
             continue
         if not isinstance(self.__query[k], dict) or not isinstance(
                 v, dict):
             raise BadQueryException(
                 'Multiple assignments to a field must all be dicts.')
         self.__query[k].update(**v)
Exemplo n.º 14
0
    def sort(self, *sort_tuples):
        ''' pymongo-style sorting.  Accepts a list of tuples.

            :param sort_tuples: varargs of sort tuples.
        '''
        query = self
        for name, direction in sort_tuples:
            field = resolve_name(self.type, name)
            if direction in (ASCENDING, 1):
                query = query.ascending(field)
            elif direction in (DESCENDING, -1):
                query = query.descending(field)
            else:
                raise BadQueryException('Bad sort direction: %s' % direction)
        return query
Exemplo n.º 15
0
    def sort(self, *sort_tuples):
        ''' pymongo-style sorting.  Accepts a list of tuples.

            :param sort_tuples: varargs of sort tuples.
        '''
        query = self
        for name, direction in sort_tuples:
            field = resolve_name(self.type, name)
            if direction in (ASCENDING, 1):
                query = query.ascending(field)
            elif direction in (DESCENDING, -1):
                query = query.descending(field)
            else:
                raise BadQueryException('Bad sort direction: %s' % direction)
        return query
Exemplo n.º 16
0
 def nin(self, qfield, *values):
     ''' Check to see that the value of ``qfield`` is not one of ``values``
         
         :param qfield: Instances of :class:`mongoalchemy.query_expression.QueryExpression`
         :param values: Values should be python values which ``qfield`` \
             understands
     '''
     # TODO: make sure that this field represents a list
     qfield = resolve_name(self.type, qfield)
     self.filter(
         QueryExpression({
             qfield: {
                 '$nin': [qfield.wrap_value(value) for value in values]
             }
         }))
     return self
Exemplo n.º 17
0
 def fields(self, *fields):
     ''' Only return the specified fields from the object.  Accessing a \
         field that was not specified in ``fields`` will result in a \
         :class:``mongoalchemy.document.FieldNotRetrieved`` exception being \
         raised
         
         :param fields: Instances of :class:``mongoalchemy.query.QueryField`` specifying \
             which fields to return
     '''
     if self._fields == None:
         self._fields = set()
     for f in fields:
         f = resolve_name(self.type, f)
         self._fields.add(f)
     self._fields.add(self.type.mongo_id)
     return self
Exemplo n.º 18
0
 def fields(self, *fields):
     ''' Only return the specified fields from the object.  Accessing a \
         field that was not specified in ``fields`` will result in a \
         :class:``mongoalchemy.document.FieldNotRetrieved`` exception being \
         raised
         
         :param fields: Instances of :class:``mongoalchemy.query.QueryField`` specifying \
             which fields to return
     '''
     if self._fields == None:
         self._fields = set()
     for f in fields:
         f = resolve_name(self.type, f)
         self._fields.add(f)
     self._fields.add(self.type.mongo_id)
     return self
Exemplo n.º 19
0
 def filter_by(self, **filters):
     ''' Filter for the names in ``filters`` being equal to the associated 
         values.  Cannot be used for sub-objects since keys must be strings'''
     for name, value in filters.iteritems():
         self.filter(resolve_name(self.type, name) == value)
     return self
Exemplo n.º 20
0
 def filter_by(self, **filters):
     ''' Filter for the names in ``filters`` being equal to the associated 
         values.  Cannot be used for sub-objects since keys must be strings'''
     for name, value in filters.iteritems():
         self.filter(resolve_name(self.type, name) == value)
     return self