Document updates

This commit is contained in:
Ross Lawley 2011-09-09 04:21:32 -07:00
parent 1631788ab6
commit bc9a09f52e
4 changed files with 55 additions and 6 deletions

View File

@ -43,6 +43,8 @@ def get_document(name):
class BaseField(object): class BaseField(object):
"""A base class for fields in a MongoDB document. Instances of this class """A base class for fields in a MongoDB document. Instances of this class
may be added to subclasses of `Document` to define a document's schema. may be added to subclasses of `Document` to define a document's schema.
.. versionchanged:: 0.5 - added verbose and help text
""" """
# Fields may have _types inserted into indexes by default # Fields may have _types inserted into indexes by default
@ -156,6 +158,8 @@ class ComplexBaseField(BaseField):
Allows for nesting of embedded documents inside complex types. Allows for nesting of embedded documents inside complex types.
Handles the lazy dereferencing of a queryset by lazily dereferencing all Handles the lazy dereferencing of a queryset by lazily dereferencing all
items in a list / dict rather than one at a time. items in a list / dict rather than one at a time.
.. versionadded:: 0.5
""" """
field = None field = None
@ -896,7 +900,6 @@ class BaseDocument(object):
return not self.__eq__(other) return not self.__eq__(other)
def __hash__(self): def __hash__(self):
""" For list, dict key """
if self.pk is None: if self.pk is None:
# For new object # For new object
return super(BaseDocument,self).__hash__() return super(BaseDocument,self).__hash__()

View File

@ -130,6 +130,11 @@ class Document(BaseDocument):
which will be used as options for the resultant ``getLastError`` command. which will be used as options for the resultant ``getLastError`` command.
For example, ``save(..., w=2, fsync=True)`` will wait until at least two servers For example, ``save(..., w=2, fsync=True)`` will wait until at least two servers
have recorded the write and will force an fsync on each server being written to. have recorded the write and will force an fsync on each server being written to.
.. versionchanged:: 0.5
In existing documents it only saves changed fields using set / unset
Saves are cascaded and any :class:`~pymongo.dbref.DBRef` objects
that have changes are saved as well.
""" """
from fields import ReferenceField, GenericReferenceField from fields import ReferenceField, GenericReferenceField
@ -226,6 +231,11 @@ class Document(BaseDocument):
signals.post_delete.send(self.__class__, document=self) signals.post_delete.send(self.__class__, document=self)
def select_related(self, max_depth=1): def select_related(self, max_depth=1):
"""Handles dereferencing of :class:`~pymongo.dbref.DBRef` objects to
a maximum depth in order to cut down the number queries to mongodb.
.. versionadded:: 0.5
"""
from dereference import dereference from dereference import dereference
self._data = dereference(self._data, max_depth) self._data = dereference(self._data, max_depth)
return self return self

View File

@ -279,7 +279,6 @@ class DateTimeField(BaseField):
return None return None
class ComplexDateTimeField(StringField): class ComplexDateTimeField(StringField):
""" """
ComplexDateTimeField handles microseconds exactly instead of rounding ComplexDateTimeField handles microseconds exactly instead of rounding
@ -295,6 +294,8 @@ class ComplexDateTimeField(StringField):
Where NNNNNN is the number of microseconds of the represented `datetime`. Where NNNNNN is the number of microseconds of the represented `datetime`.
The `,` as the separator can be easily modified by passing the `separator` The `,` as the separator can be easily modified by passing the `separator`
keyword when initializing the field. keyword when initializing the field.
.. versionadded:: 0.5
""" """
def __init__(self, separator=',', **kwargs): def __init__(self, separator=',', **kwargs):
@ -478,6 +479,7 @@ class DictField(ComplexBaseField):
similar to an embedded document, but the structure is not defined. similar to an embedded document, but the structure is not defined.
.. versionadded:: 0.3 .. versionadded:: 0.3
.. versionchanged:: 0.5 - Can now handle complex / varying types of data
""" """
def __init__(self, basecls=None, field=None, *args, **kwargs): def __init__(self, basecls=None, field=None, *args, **kwargs):
@ -542,6 +544,8 @@ class ReferenceField(BaseField):
* NULLIFY - Updates the reference to null. * NULLIFY - Updates the reference to null.
* CASCADE - Deletes the documents associated with the reference. * CASCADE - Deletes the documents associated with the reference.
* DENY - Prevent the deletion of the reference object. * DENY - Prevent the deletion of the reference object.
.. versionchanged:: 0.5 added `reverse_delete_rule`
""" """
def __init__(self, document_type, reverse_delete_rule=DO_NOTHING, **kwargs): def __init__(self, document_type, reverse_delete_rule=DO_NOTHING, **kwargs):
@ -708,6 +712,7 @@ class GridFSProxy(object):
"""Proxy object to handle writing and reading of files to and from GridFS """Proxy object to handle writing and reading of files to and from GridFS
.. versionadded:: 0.4 .. versionadded:: 0.4
.. versionchanged:: 0.5 - added optional size param to read
""" """
def __init__(self, grid_id=None, key=None, instance=None): def __init__(self, grid_id=None, key=None, instance=None):
@ -800,6 +805,7 @@ class FileField(BaseField):
"""A GridFS storage field. """A GridFS storage field.
.. versionadded:: 0.4 .. versionadded:: 0.4
.. versionchanged:: 0.5 added optional size param for read
""" """
def __init__(self, **kwargs): def __init__(self, **kwargs):

View File

@ -346,7 +346,10 @@ class QuerySet(object):
self._hint = -1 # Using -1 as None is a valid value for hint self._hint = -1 # Using -1 as None is a valid value for hint
def clone(self): def clone(self):
"""Creates a copy of the current :class:`~mongoengine.queryset.QuerySet`""" """Creates a copy of the current :class:`~mongoengine.queryset.QuerySet`
.. versionadded:: 0.5
"""
c = self.__class__(self._document, self._collection_obj) c = self.__class__(self._document, self._collection_obj)
copy_props = ('_initial_query', '_query_obj', '_where_clause', copy_props = ('_initial_query', '_query_obj', '_where_clause',
@ -996,6 +999,8 @@ class QuerySet(object):
Hinting will not do anything if the corresponding index does not exist. Hinting will not do anything if the corresponding index does not exist.
The last hint applied to this cursor takes precedence over all others. The last hint applied to this cursor takes precedence over all others.
.. versionadded:: 0.5
""" """
self._cursor.hint(index) self._cursor.hint(index)
self._hint = index self._hint = index
@ -1038,11 +1043,12 @@ class QuerySet(object):
def only(self, *fields): def only(self, *fields):
"""Load only a subset of this document's fields. :: """Load only a subset of this document's fields. ::
post = BlogPost.objects(...).only("title") post = BlogPost.objects(...).only("title", "author.name")
:param fields: fields to include :param fields: fields to include
.. versionadded:: 0.3 .. versionadded:: 0.3
.. versionchanged:: 0.5 - Added subfield support
""" """
fields = dict([(f, QueryFieldList.ONLY) for f in fields]) fields = dict([(f, QueryFieldList.ONLY) for f in fields])
return self.fields(**fields) return self.fields(**fields)
@ -1053,6 +1059,8 @@ class QuerySet(object):
post = BlogPost.objects(...).exclude("comments") post = BlogPost.objects(...).exclude("comments")
:param fields: fields to exclude :param fields: fields to exclude
.. versionadded:: 0.5
""" """
fields = dict([(f, QueryFieldList.EXCLUDE) for f in fields]) fields = dict([(f, QueryFieldList.EXCLUDE) for f in fields])
return self.fields(**fields) return self.fields(**fields)
@ -1098,6 +1106,8 @@ class QuerySet(object):
"""Include all fields. Reset all previously calls of .only() and .exclude(). :: """Include all fields. Reset all previously calls of .only() and .exclude(). ::
post = BlogPost.objects(...).exclude("comments").only("title").all_fields() post = BlogPost.objects(...).exclude("comments").only("title").all_fields()
.. versionadded:: 0.5
""" """
self._loaded_fields = QueryFieldList(always_include=self._loaded_fields.always_include) self._loaded_fields = QueryFieldList(always_include=self._loaded_fields.always_include)
return self return self
@ -1153,6 +1163,8 @@ class QuerySet(object):
"""Enable or disable snapshot mode when querying. """Enable or disable snapshot mode when querying.
:param enabled: whether or not snapshot mode is enabled :param enabled: whether or not snapshot mode is enabled
..versionchanged:: 0.5 - made chainable
""" """
self._snapshot = enabled self._snapshot = enabled
return self return self
@ -1161,6 +1173,8 @@ class QuerySet(object):
"""Enable or disable the default mongod timeout when querying. """Enable or disable the default mongod timeout when querying.
:param enabled: whether or not the timeout is used :param enabled: whether or not the timeout is used
..versionchanged:: 0.5 - made chainable
""" """
self._timeout = enabled self._timeout = enabled
return self return self
@ -1404,6 +1418,8 @@ class QuerySet(object):
.. note:: When using this mode of query, the database will call your .. note:: When using this mode of query, the database will call your
function, or evaluate your predicate clause, for each object function, or evaluate your predicate clause, for each object
in the collection. in the collection.
.. versionadded:: 0.5
""" """
where_clause = self._sub_js_fields(where_clause) where_clause = self._sub_js_fields(where_clause)
self._where_clause = where_clause self._where_clause = where_clause
@ -1414,6 +1430,9 @@ class QuerySet(object):
:param field: the field to sum over; use dot-notation to refer to :param field: the field to sum over; use dot-notation to refer to
embedded document fields embedded document fields
.. versionchanged:: 0.5 - updated to map_reduce as db.eval doesnt work
with sharding.
""" """
map_func = pymongo.code.Code(""" map_func = pymongo.code.Code("""
function() { function() {
@ -1441,6 +1460,9 @@ class QuerySet(object):
:param field: the field to average over; use dot-notation to refer to :param field: the field to average over; use dot-notation to refer to
embedded document fields embedded document fields
.. versionchanged:: 0.5 - updated to map_reduce as db.eval doesnt work
with sharding.
""" """
map_func = pymongo.code.Code(""" map_func = pymongo.code.Code("""
function() { function() {
@ -1472,7 +1494,6 @@ class QuerySet(object):
else: else:
return 0 return 0
def item_frequencies(self, field, normalize=False, map_reduce=True): def item_frequencies(self, field, normalize=False, map_reduce=True):
"""Returns a dictionary of all items present in a field across """Returns a dictionary of all items present in a field across
the whole queried set of documents, and their corresponding frequency. the whole queried set of documents, and their corresponding frequency.
@ -1490,6 +1511,9 @@ class QuerySet(object):
:param field: the field to use :param field: the field to use
:param normalize: normalize the results so they add to 1.0 :param normalize: normalize the results so they add to 1.0
:param map_reduce: Use map_reduce over exec_js :param map_reduce: Use map_reduce over exec_js
.. versionchanged:: 0.5 defaults to map_reduce and can handle embedded
document lookups
""" """
if map_reduce: if map_reduce:
return self._item_frequencies_map_reduce(field, normalize=normalize) return self._item_frequencies_map_reduce(field, normalize=normalize)
@ -1594,9 +1618,15 @@ class QuerySet(object):
return repr(data) return repr(data)
def select_related(self, max_depth=1): def select_related(self, max_depth=1):
"""Handles dereferencing of :class:`~pymongo.dbref.DBRef` objects to
a maximum depth in order to cut down the number queries to mongodb.
.. versionadded:: 0.5
"""
from dereference import dereference from dereference import dereference
return dereference(self, max_depth=max_depth) return dereference(self, max_depth=max_depth)
class QuerySetManager(object): class QuerySetManager(object):
get_queryset = None get_queryset = None