Compare commits

...

6 Commits

Author SHA1 Message Date
Ross Lawley
4defc82192 Version Bump 2012-09-11 15:16:39 +00:00
Ross Lawley
5949970a95 Fixed index inheritance issues
firmed up testcases (MongoEngine/mongoengine#123) (MongoEngine/mongoengine#125)
2012-09-11 15:14:37 +00:00
Ross Lawley
5c6035d636 Updated upgrade docs for BinaryFields 2012-09-11 08:56:32 +00:00
Ross Lawley
a2183e3dcc Reverted EmbeddedDocuments meta handling.
You now can turn off inheritance (MongoEngine/mongoengine#119)
2012-09-07 13:23:46 +01:00
Ross Lawley
99637151b5 Updated version 2012-09-05 10:24:25 +01:00
Ross Lawley
a8e787c120 Update index spec generation so its not destructive (MongoEngine/mongoengine#113) 2012-09-04 14:39:19 +01:00
8 changed files with 136 additions and 21 deletions

View File

@@ -2,6 +2,19 @@
Changelog
=========
Changes in 0.7.4
================
- Fixed index inheritance issues - firmed up testcases (MongoEngine/mongoengine#123) (MongoEngine/mongoengine#125)
Changes in 0.7.3
================
- Reverted EmbeddedDocuments meta handling - now can turn off inheritance (MongoEngine/mongoengine#119)
Changes in 0.7.2
================
- Update index spec generation so its not destructive (MongoEngine/mongoengine#113)
Changes in 0.7.1
=================
- Fixed index spec inheritance (MongoEngine/mongoengine#111)

View File

@@ -61,6 +61,13 @@ stored in rather than as string representations. Your code may need to be
updated to handle native types rather than strings keys for the results of
item frequency queries.
BinaryFields
------------
Binary fields have been updated so that they are native binary types. If you
previously were doing `str` comparisons with binary field values you will have
to update and wrap the value in a `str`.
0.5 to 0.6
==========

View File

@@ -12,7 +12,7 @@ from signals import *
__all__ = (document.__all__ + fields.__all__ + connection.__all__ +
queryset.__all__ + signals.__all__)
VERSION = (0, 7, 1)
VERSION = (0, 7, 4)
def get_version():

View File

@@ -508,6 +508,10 @@ class DocumentMetaclass(type):
attrs['_is_document'] = attrs.get('_is_document', False)
# EmbeddedDocuments could have meta data for inheritance
if 'meta' in attrs:
attrs['_meta'] = attrs.pop('meta')
# Handle document Fields
# Merge all fields from subclasses
@@ -571,6 +575,24 @@ class DocumentMetaclass(type):
superclasses[base._class_name] = base
superclasses.update(base._superclasses)
if hasattr(base, '_meta'):
# Warn if allow_inheritance isn't set and prevent
# inheritance of classes where inheritance is set to False
allow_inheritance = base._meta.get('allow_inheritance',
ALLOW_INHERITANCE)
if (not getattr(base, '_is_base_cls', True)
and allow_inheritance is None):
warnings.warn(
"%s uses inheritance, the default for "
"allow_inheritance is changing to off by default. "
"Please add it to the document meta." % name,
FutureWarning
)
elif (allow_inheritance == False and
not base._meta.get('abstract')):
raise ValueError('Document %s may not be subclassed' %
base.__name__)
attrs['_class_name'] = '.'.join(reversed(class_name))
attrs['_superclasses'] = superclasses
@@ -745,21 +767,6 @@ class TopLevelDocumentMetaclass(DocumentMetaclass):
if hasattr(base, 'meta'):
meta.merge(base.meta)
elif hasattr(base, '_meta'):
# Warn if allow_inheritance isn't set and prevent
# inheritance of classes where inheritance is set to False
allow_inheritance = base._meta.get('allow_inheritance',
ALLOW_INHERITANCE)
if not base._is_base_cls and allow_inheritance is None:
warnings.warn(
"%s uses inheritance, the default for "
"allow_inheritance is changing to off by default. "
"Please add it to the document meta." % name,
FutureWarning
)
elif (allow_inheritance == False and
not base._meta.get('abstract')):
raise ValueError('Document %s may not be subclassed' %
base.__name__)
meta.merge(base._meta)
# Set collection in the meta if its callable

View File

@@ -25,6 +25,14 @@ class EmbeddedDocument(BaseDocument):
collection. :class:`~mongoengine.EmbeddedDocument`\ s should be used as
fields on :class:`~mongoengine.Document`\ s through the
:class:`~mongoengine.EmbeddedDocumentField` field type.
A :class:`~mongoengine.EmbeddedDocument` subclass may be itself subclassed,
to create a specialised version of the embedded document that will be
stored in the same collection. To facilitate this behaviour, `_cls` and
`_types` fields are added to documents (hidden though the MongoEngine
interface though). To disable this behaviour and remove the dependence on
the presence of `_cls` and `_types`, set :attr:`allow_inheritance` to
``False`` in the :attr:`meta` dictionary.
"""
# The __metaclass__ attribute is removed by 2to3 when running with Python3

View File

@@ -398,6 +398,7 @@ class QuerySet(object):
or a **-** to determine the index ordering
"""
index_spec = QuerySet._build_index_spec(self._document, key_or_list)
index_spec = index_spec.copy()
fields = index_spec.pop('fields')
index_spec['drop_dups'] = drop_dups
index_spec['background'] = background
@@ -472,7 +473,9 @@ class QuerySet(object):
# Ensure document-defined indexes are created
if self._document._meta['index_specs']:
for spec in self._document._meta['index_specs']:
index_spec = self._document._meta['index_specs']
for spec in index_spec:
spec = spec.copy()
fields = spec.pop('fields')
types_indexed = types_indexed or includes_types(fields)
opts = index_opts.copy()
@@ -498,8 +501,10 @@ class QuerySet(object):
"""
if isinstance(spec, basestring):
spec = {'fields': [spec]}
if isinstance(spec, (list, tuple)):
spec = {'fields': spec}
elif isinstance(spec, (list, tuple)):
spec = {'fields': list(spec)}
elif isinstance(spec, dict):
spec = dict(spec)
index_list = []
direction = None

View File

@@ -5,7 +5,7 @@
%define srcname mongoengine
Name: python-%{srcname}
Version: 0.7.1
Version: 0.7.4
Release: 1%{?dist}
Summary: A Python Document-Object Mapper for working with MongoDB

View File

@@ -338,7 +338,6 @@ class DocumentTest(unittest.TestCase):
meta = {'allow_inheritance': False}
self.assertRaises(ValueError, create_employee_class)
def test_allow_inheritance_abstract_document(self):
"""Ensure that abstract documents can set inheritance rules and that
_cls and _types will not be used.
@@ -366,6 +365,31 @@ class DocumentTest(unittest.TestCase):
Animal.drop_collection()
def test_allow_inheritance_embedded_document(self):
# Test the same for embedded documents
class Comment(EmbeddedDocument):
content = StringField()
meta = {'allow_inheritance': False}
def create_special_comment():
class SpecialComment(Comment):
pass
self.assertRaises(ValueError, create_special_comment)
comment = Comment(content='test')
self.assertFalse('_cls' in comment.to_mongo())
self.assertFalse('_types' in comment.to_mongo())
class Comment(EmbeddedDocument):
content = StringField()
meta = {'allow_inheritance': True}
comment = Comment(content='test')
self.assertTrue('_cls' in comment.to_mongo())
self.assertTrue('_types' in comment.to_mongo())
def test_document_inheritance(self):
"""Ensure mutliple inheritance of abstract docs works
"""
@@ -396,6 +420,9 @@ class DocumentTest(unittest.TestCase):
'indexes': ['name']
}
self.assertEqual(Animal._meta['index_specs'],
[{'fields': [('_types', 1), ('name', 1)]}])
Animal.drop_collection()
dog = Animal(name='dog')
@@ -417,6 +444,9 @@ class DocumentTest(unittest.TestCase):
'allow_inheritance': False,
'indexes': ['name']
}
self.assertEqual(Animal._meta['index_specs'],
[{'fields': [('name', 1)]}])
collection.update({}, {"$unset": {"_types": 1, "_cls": 1}}, multi=True)
# Confirm extra data is removed
@@ -634,6 +664,12 @@ class DocumentTest(unittest.TestCase):
'allow_inheritance': True
}
self.assertEqual(BlogPost._meta['index_specs'],
[{'fields': [('_types', 1), ('addDate', -1)]},
{'fields': [('tags', 1)]},
{'fields': [('_types', 1), ('category', 1),
('addDate', -1)]}])
BlogPost.drop_collection()
info = BlogPost.objects._collection.index_information()
@@ -657,6 +693,13 @@ class DocumentTest(unittest.TestCase):
title = StringField()
meta = {'indexes': ['title']}
self.assertEqual(ExtendedBlogPost._meta['index_specs'],
[{'fields': [('_types', 1), ('addDate', -1)]},
{'fields': [('tags', 1)]},
{'fields': [('_types', 1), ('category', 1),
('addDate', -1)]},
{'fields': [('_types', 1), ('title', 1)]}])
BlogPost.drop_collection()
list(ExtendedBlogPost.objects)
@@ -687,6 +730,27 @@ class DocumentTest(unittest.TestCase):
description = StringField()
self.assertEqual(A._meta['index_specs'], B._meta['index_specs'])
self.assertEqual([{'fields': [('_types', 1), ('title', 1)]}],
A._meta['index_specs'])
def test_build_index_spec_is_not_destructive(self):
class MyDoc(Document):
keywords = StringField()
meta = {
'indexes': ['keywords'],
'allow_inheritance': False
}
self.assertEqual(MyDoc._meta['index_specs'],
[{'fields': [('keywords', 1)]}])
# Force index creation
MyDoc.objects._ensure_indexes()
self.assertEqual(MyDoc._meta['index_specs'],
[{'fields': [('keywords', 1)]}])
def test_db_field_load(self):
"""Ensure we load data correctly
@@ -748,6 +812,9 @@ class DocumentTest(unittest.TestCase):
'allow_inheritance': False
}
self.assertEqual([{'fields': [('rank.title', 1)]}],
Person._meta['index_specs'])
Person.drop_collection()
# Indexes are lazy so use list() to perform query
@@ -766,6 +833,10 @@ class DocumentTest(unittest.TestCase):
'*location.point',
],
}
self.assertEqual([{'fields': [('location.point', '2d')]}],
Place._meta['index_specs'])
Place.drop_collection()
info = Place.objects._collection.index_information()
@@ -791,6 +862,10 @@ class DocumentTest(unittest.TestCase):
],
}
self.assertEqual([{'fields': [('addDate', -1)], 'unique': True,
'sparse': True, 'types': False}],
BlogPost._meta['index_specs'])
BlogPost.drop_collection()
info = BlogPost.objects._collection.index_information()