Changed default collection naming

Also added upgrade text
This commit is contained in:
Ross Lawley 2011-06-20 14:00:06 +01:00
parent f41c5217c6
commit e3cd398f70
5 changed files with 139 additions and 14 deletions

View File

@ -5,6 +5,7 @@ Changelog
Changes in dev Changes in dev
============== ==============
- Updated default collection naming convention
- Added Document Mixin support - Added Document Mixin support
- Fixed queryet __repr__ mid iteration - Fixed queryet __repr__ mid iteration
- Added hint() support, so cantell Mongo the proper index to use for the query - Added hint() support, so cantell Mongo the proper index to use for the query

View File

@ -2,7 +2,7 @@
MongoEngine User Documentation MongoEngine User Documentation
============================== ==============================
MongoEngine is an Object-Document Mapper, written in Python for working with MongoEngine is an Object-Document Mapper, written in Python for working with
MongoDB. To install it, simply run MongoDB. To install it, simply run
.. code-block:: console .. code-block:: console
@ -15,7 +15,7 @@ To get help with using MongoEngine, use the `MongoEngine Users mailing list
<http://groups.google.com/group/mongoengine-users>`_ or come chat on the <http://groups.google.com/group/mongoengine-users>`_ or come chat on the
`#mongoengine IRC channel <irc://irc.freenode.net/mongoengine>`_. `#mongoengine IRC channel <irc://irc.freenode.net/mongoengine>`_.
If you are interested in contributing, join the developers' `mailing list If you are interested in contributing, join the developers' `mailing list
<http://groups.google.com/group/mongoengine-dev>`_. <http://groups.google.com/group/mongoengine-dev>`_.
.. toctree:: .. toctree::
@ -26,6 +26,7 @@ If you are interested in contributing, join the developers' `mailing list
apireference apireference
django django
changelog changelog
upgrading
Indices and tables Indices and tables
================== ==================

73
docs/upgrade.rst Normal file
View File

@ -0,0 +1,73 @@
=========
Upgrading
=========
0.4 to 0.5
===========
There have been the following backwards incompatibilities from 0.4 to 0.5:
#. Default collection naming.
Previously it was just lowercase, its now much more pythonic and readable as its
lowercase and underscores, previously ::
class MyAceDocument(Document):
pass
MyAceDocument._meta['collection'] == myacedocument
In 0.5 this will change to ::
class MyAceDocument(Document):
pass
MyAceDocument._get_collection_name() == my_ace_document
To upgrade use a Mixin class to set meta like so ::
class BaseMixin(object):
meta = {
'collection': lambda c: c.__name__.lower()
}
class MyAceDocument(Document, BaseMixin):
pass
MyAceDocument._get_collection_name() == myacedocument
Alternatively, you can rename your collections eg ::
from mongoengine.connection import _get_db
from mongoengine.base import _document_registry
def rename_collections():
db = _get_db()
failure = False
collection_names = [d._get_collection_name() for d in _document_registry.values()]
for new_style_name in collection_names:
if not new_style_name: # embedded documents don't have collections
continue
old_style_name = new_style_name.replace('_', '')
if old_style_name == new_style_name:
continue # Nothing to do
existing = db.collection_names()
if old_style_name in existing:
if new_style_name in existing:
failure = True
print "FAILED to rename: %s to %s (already exists)" % (
old_style_name, new_style_name)
else:
db[old_style_name].rename(new_style_name)
print "Renamed: %s to %s" % (old_style_name, new_style_name)
if failure:
print "Upgrading collection names failed"
else:
print "Upgraded collection names"

View File

@ -492,7 +492,7 @@ class TopLevelDocumentMetaclass(DocumentMetaclass):
raise ValueError("Abstract document cannot have non-abstract base") raise ValueError("Abstract document cannot have non-abstract base")
return super_new(cls, name, bases, attrs) return super_new(cls, name, bases, attrs)
collection = name.lower() collection = ''.join('_%s' % c if c.isupper() else c for c in name).strip('_').lower()
id_field = None id_field = None
base_indexes = [] base_indexes = []

View File

@ -62,22 +62,72 @@ class DocumentTest(unittest.TestCase):
# Ensure Document isn't treated like an actual document # Ensure Document isn't treated like an actual document
self.assertFalse(hasattr(Document, '_fields')) self.assertFalse(hasattr(Document, '_fields'))
def test_dynamic_collection_naming(self): def test_collection_name(self):
"""Ensure that a collection with a specified name may be used.
"""
def create_collection_name(cls): class DefaultNamingTest(Document):
return "PERSON" pass
self.assertEquals('default_naming_test', DefaultNamingTest._get_collection_name())
class DynamicPerson(Document): class CustomNamingTest(Document):
name = StringField() meta = {'collection': 'pimp_my_collection'}
age = IntField()
meta = {'collection': create_collection_name} self.assertEquals('pimp_my_collection', CustomNamingTest._get_collection_name())
collection = DynamicPerson._get_collection_name() class DynamicNamingTest(Document):
self.assertEquals(collection, 'PERSON') meta = {'collection': lambda c: "DYNAMO"}
self.assertEquals('DYNAMO', DynamicNamingTest._get_collection_name())
DynamicPerson(name='Test User', age=30).save() # Use Abstract class to handle backwards compatibility
self.assertTrue(collection in self.db.collection_names()) class BaseDocument(Document):
meta = {
'abstract': True,
'collection': lambda c: c.__name__.lower()
}
class OldNamingConvention(BaseDocument):
pass
self.assertEquals('oldnamingconvention', OldNamingConvention._get_collection_name())
class InheritedAbstractNamingTest(BaseDocument):
meta = {'collection': 'wibble'}
self.assertEquals('wibble', InheritedAbstractNamingTest._get_collection_name())
with warnings.catch_warnings(record=True) as w:
# Cause all warnings to always be triggered.
warnings.simplefilter("always")
class NonAbstractBase(Document):
pass
class InheritedDocumentFailTest(NonAbstractBase):
meta = {'collection': 'fail'}
self.assertTrue(issubclass(w[0].category, SyntaxWarning))
self.assertEquals('non_abstract_base', InheritedDocumentFailTest._get_collection_name())
# Mixin tests
class BaseMixin(object):
meta = {
'collection': lambda c: c.__name__.lower()
}
class OldMixinNamingConvention(Document, BaseMixin):
pass
self.assertEquals('oldmixinnamingconvention', OldMixinNamingConvention._get_collection_name())
class BaseMixin(object):
meta = {
'collection': lambda c: c.__name__.lower()
}
class BaseDocument(Document, BaseMixin):
pass
class MyDocument(BaseDocument):
pass
self.assertEquals('mydocument', OldMixinNamingConvention._get_collection_name())
def test_get_superclasses(self): def test_get_superclasses(self):
"""Ensure that the correct list of superclasses is assembled. """Ensure that the correct list of superclasses is assembled.