Compare commits

..
6 changed files with 37 additions and 74 deletions
-5
View File
@@ -6,11 +6,6 @@ Development
=========== ===========
- (Fill this out as you fix issues and develop your features). - (Fill this out as you fix issues and develop your features).
Changes in 0.13.0
=================
- POTENTIAL BREAKING CHANGE: Added Unicode support to the `EmailField`, see
docs/upgrade.rst for details.
Changes in 0.12.0 Changes in 0.12.0
================= =================
- POTENTIAL BREAKING CHANGE: Fixed limit/skip/hint/batch_size chaining #1476 - POTENTIAL BREAKING CHANGE: Fixed limit/skip/hint/batch_size chaining #1476
+1 -4
View File
@@ -206,10 +206,7 @@ object::
ross.last_name = 'Lawley' ross.last_name = 'Lawley'
ross.save() ross.save()
Assign another user to a variable called ``john``, just like we did above with Now that we've got our user in the database, let's add a couple of posts::
``ross``.
Now that we've got our users in the database, let's add a couple of posts::
post1 = TextPost(title='Fun with MongoEngine', author=john) post1 = TextPost(title='Fun with MongoEngine', author=john)
post1.content = 'Took a look at MongoEngine today, looks pretty cool.' post1.content = 'Took a look at MongoEngine today, looks pretty cool.'
-11
View File
@@ -6,17 +6,6 @@ Development
*********** ***********
(Fill this out whenever you introduce breaking changes to MongoEngine) (Fill this out whenever you introduce breaking changes to MongoEngine)
0.13.0
******
This release adds Unicode support to the `EmailField` and changes its
structure significantly. Previously, email addresses containing Unicode
characters didn't work at all. Starting with v0.13.0, domains with Unicode
characters are supported out of the box, meaning some emails that previously
didn't pass validation now do. Make sure the rest of your application can
accept such email addresses. Additionally, if you subclassed the `EmailField`
in your application and overrode `EmailField.EMAIL_REGEX`, you will have to
adjust your code to override `EmailField.USER_REGEX`, `EmailField.DOMAIN_REGEX`,
and potentially `EmailField.UTF8_USER_REGEX`.
0.12.0 0.12.0
****** ******
+1 -1
View File
@@ -23,7 +23,7 @@ __all__ = (list(document.__all__) + list(fields.__all__) +
list(signals.__all__) + list(errors.__all__)) list(signals.__all__) + list(errors.__all__))
VERSION = (0, 13, 0) VERSION = (0, 12, 0)
def get_version(): def get_version():
+27 -45
View File
@@ -167,62 +167,44 @@ class Document(BaseDocument):
@classmethod @classmethod
def _get_collection(cls): def _get_collection(cls):
"""Return a PyMongo collection for the document.""" """Returns the collection for the document."""
# TODO: use new get_collection() with PyMongo3 ?
if not hasattr(cls, '_collection') or cls._collection is None: if not hasattr(cls, '_collection') or cls._collection is None:
db = cls._get_db()
# Get the collection, either capped or regular. collection_name = cls._get_collection_name()
# Create collection as a capped collection if specified
if cls._meta.get('max_size') or cls._meta.get('max_documents'): if cls._meta.get('max_size') or cls._meta.get('max_documents'):
cls._collection = cls._get_capped_collection() # Get max document limit and max byte size from meta
else:
db = cls._get_db()
collection_name = cls._get_collection_name()
cls._collection = db[collection_name]
# Ensure indexes on the collection unless auto_create_index was
# set to False.
if cls._meta.get('auto_create_index', True):
cls.ensure_indexes()
return cls._collection
@classmethod
def _get_capped_collection(cls):
"""Create a new or get an existing capped PyMongo collection."""
db = cls._get_db()
collection_name = cls._get_collection_name()
# Get max document limit and max byte size from meta.
max_size = cls._meta.get('max_size') or 10 * 2 ** 20 # 10MB default max_size = cls._meta.get('max_size') or 10 * 2 ** 20 # 10MB default
max_documents = cls._meta.get('max_documents') max_documents = cls._meta.get('max_documents')
# Round up to next 256 bytes as MongoDB would do it to avoid exception
# MongoDB will automatically raise the size to make it a multiple of
# 256 bytes. We raise it here ourselves to be able to reliably compare
# the options below.
if max_size % 256: if max_size % 256:
max_size = (max_size // 256 + 1) * 256 max_size = (max_size // 256 + 1) * 256
# If the collection already exists and has different options
# (i.e. isn't capped or has different max/size), raise an error.
if collection_name in db.collection_names(): if collection_name in db.collection_names():
collection = db[collection_name] cls._collection = db[collection_name]
options = collection.options() # The collection already exists, check if its capped
if ( # options match the specified capped options
options.get('max') != max_documents or options = cls._collection.options()
options.get('size') != max_size if options.get('max') != max_documents or \
): options.get('size') != max_size:
raise InvalidCollectionError( msg = (('Cannot create collection "%s" as a capped '
'Cannot create collection "{}" as a capped ' 'collection as it already exists')
'collection as it already exists'.format(cls._collection) % cls._collection)
) raise InvalidCollectionError(msg)
else:
return collection # Create the collection as a capped collection
# Create a new capped collection.
opts = {'capped': True, 'size': max_size} opts = {'capped': True, 'size': max_size}
if max_documents: if max_documents:
opts['max'] = max_documents opts['max'] = max_documents
cls._collection = db.create_collection(
return db.create_collection(collection_name, **opts) collection_name, **opts
)
else:
cls._collection = db[collection_name]
if cls._meta.get('auto_create_index', True):
cls.ensure_indexes()
return cls._collection
def to_mongo(self, *args, **kwargs): def to_mongo(self, *args, **kwargs):
data = super(Document, self).to_mongo(*args, **kwargs) data = super(Document, self).to_mongo(*args, **kwargs)
+3 -3
View File
@@ -608,9 +608,9 @@ class EmbeddedDocumentField(BaseField):
""" """
def __init__(self, document_type, **kwargs): def __init__(self, document_type, **kwargs):
if not ( if (
isinstance(document_type, six.string_types) or not isinstance(document_type, six.string_types) and
issubclass(document_type, EmbeddedDocument) not issubclass(document_type, EmbeddedDocument)
): ):
self.error('Invalid embedded document class provided to an ' self.error('Invalid embedded document class provided to an '
'EmbeddedDocumentField') 'EmbeddedDocumentField')