Changed default collection naming
Also added upgrade text
This commit is contained in:
parent
f41c5217c6
commit
e3cd398f70
@ -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
|
||||||
|
@ -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
73
docs/upgrade.rst
Normal 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"
|
||||||
|
|
@ -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 = []
|
||||||
|
@ -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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user