From 94ae4ad8b00b2eed0eee29c6ed2cea4a18c60cdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilo=20L=C3=B3pez?= Date: Wed, 18 Nov 2015 18:31:08 -0300 Subject: [PATCH 1/4] EmbeddedDoc. prepare_query_value for None value If EmbeddedDocument is None on filter, Mongoengine was crashing. --- mongoengine/fields.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mongoengine/fields.py b/mongoengine/fields.py index f58993111..d70d70d92 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -566,6 +566,8 @@ def lookup_member(self, member_name): return self.document_type._fields.get(member_name) def prepare_query_value(self, op, value): + if value is None: + return None if not isinstance(value, self.document_type): value = self.document_type._from_son(value) super(EmbeddedDocumentField, self).prepare_query_value(op, value) From 91c0d71bff42180b79f47970bfe803c6996079b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilo=20L=C3=B3pez?= Date: Wed, 18 Nov 2015 19:08:06 -0300 Subject: [PATCH 2/4] fix If value._instance is not defined, crashing --- mongoengine/base/datastructures.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongoengine/base/datastructures.py b/mongoengine/base/datastructures.py index e4d2b3922..fa79689bd 100644 --- a/mongoengine/base/datastructures.py +++ b/mongoengine/base/datastructures.py @@ -113,7 +113,7 @@ def __getitem__(self, key, *args, **kwargs): value = super(BaseList, self).__getitem__(key) EmbeddedDocument = _import_class('EmbeddedDocument') - if isinstance(value, EmbeddedDocument) and value._instance is None: + if isinstance(value, EmbeddedDocument) and getattr(value, '_instance', None) is None: value._instance = self._instance elif not isinstance(value, BaseDict) and isinstance(value, dict): value = BaseDict(value, None, '%s.%s' % (self._name, key)) From de320edcc5786b65dd77e9c543529a27cd09e3bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilo=20L=C3=B3pez?= Date: Wed, 18 Nov 2015 19:11:10 -0300 Subject: [PATCH 3/4] filter for empty lists on embedded fields, crash. --- mongoengine/fields.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mongoengine/fields.py b/mongoengine/fields.py index d70d70d92..ccbbb0a48 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -566,8 +566,13 @@ def lookup_member(self, member_name): return self.document_type._fields.get(member_name) def prepare_query_value(self, op, value): + if value is None: - return None + return value + + if isinstance(value, list) and len(value) == 0: + return value + if not isinstance(value, self.document_type): value = self.document_type._from_son(value) super(EmbeddedDocumentField, self).prepare_query_value(op, value) From cf75dac1c612ca21e32f403348b77c1da7766703 Mon Sep 17 00:00:00 2001 From: clopez Date: Tue, 23 Aug 2016 10:34:58 -0300 Subject: [PATCH 4/4] Hotfix on mongoengine making field not update correctly when updating parent. We had the following changes to an object: obj.something obj.data.rut obj.data._rut obj.data._dv Then a big change over the obj.data field was made, thus leaving changes like this: obj.something obj.data But instead we where getting: obj.something obj.data obj.data._rut Then the mongodb operation raised an error of the incompatible $set operation trying to change data._rut and data at the same time. Mongoengine had a bug because it was deleting elements on the list while iterating it. This fixes the issue copying the list, so we iterate over the copy while we remove elements on the original. --- mongoengine/base/document.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index 6353162ab..f6b1ce7a2 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -491,7 +491,7 @@ def _mark_as_changed(self, key): # remove lower level changed fields level = '.'.join(levels[:idx]) + '.' remove = self._changed_fields.remove - for field in self._changed_fields: + for field in copy.copy(self._changed_fields): if field.startswith(level): remove(field)