Skip to content

Commit

Permalink
Merge pull request #104 from christ0pher/master
Browse files Browse the repository at this point in the history
Overwritten values with DynamicFields if two versions of the same document-definition exist
  • Loading branch information
heynemann committed Nov 3, 2015
2 parents 3354ed0 + 7edf02c commit e75fd58
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 1 deletion.
3 changes: 2 additions & 1 deletion motorengine/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def is_embedded_field(self, field):

@classmethod
def from_son(cls, dic):
from motorengine.fields.dynamic_field import DynamicField
field_values = {}
for name, value in dic.items():
field = cls.get_field_by_db_name(name)
Expand Down Expand Up @@ -295,7 +296,7 @@ def __setattr__(self, name, value):
@classmethod
def get_field_by_db_name(cls, name):
for field_name, field in cls._fields.items():
if name == field.db_field:
if name == field.db_field or name.lstrip("_") == field.db_field:
return field
return None

Expand Down
60 changes: 60 additions & 0 deletions tests/test_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,66 @@ class DynamicFieldDocument(Document):

expect(document_count).to_equal(1)

def test_dynamic_fields_with_two_version_fields(self):

class Version1Document(Document):
__collection__ = "TestDynamicFieldDocumentQuery1"
old_element = StringField(default="old_string_field")

class Version2Document(Document):
__collection__ = "TestDynamicFieldDocumentQuery1"
old_element = StringField(default="old_string_field")
new_element = StringField(default="new_string_field")


self.drop_coll(Version1Document.__collection__)

doc1 = Version1Document()
doc1.old_element = "my_old_string_field1"
doc1.save(callback=self.stop)
doc1 = self.wait()

doc2 = Version2Document()
doc2.old_element = "my_old_string_field2"
doc2.new_element = "my_new_string_field2"
doc2.save(callback=self.stop)
doc2 = self.wait()

# Querying with the old Version1.
# This effect happens when you have 2 different services using different versions of the document.
# When editing the version1 document, no _dynfield value should be added because version2 will
# eventually overwrite real values from new_field.
Version1Document.objects.get(old_element="my_old_string_field2", callback=self.stop)
doc2_with_version1 = self.wait()

expect(doc2_with_version1._id).not_to_be_null()
expect(doc2_with_version1.old_element).to_equal("my_old_string_field2")
expect(doc2_with_version1.new_element).to_equal("my_new_string_field2")

Version1Document.objects.get(old_element="my_old_string_field2", callback=self.stop)
doc2_with_version1 = self.wait()

expect(doc2_with_version1._id).not_to_be_null()
expect(doc2_with_version1.old_element).to_equal("my_old_string_field2")
expect(doc2_with_version1.new_element).to_equal("my_new_string_field2")

# Changing one field and saving it.
doc2_with_version1.old_element = "my_old_string_field2_modified"
doc2_with_version1.save(callback=self.stop)
doc2_with_version1 = self.wait()
# The database should contain the dynamic field.
# Querying with the new version should not overwrite the data.
Version2Document.objects.get(old_element="my_old_string_field2_modified", callback=self.stop)
doc2_with_version2 = self.wait()
expect(doc2_with_version2._id).not_to_be_null()
expect(doc2_with_version2.old_element).to_equal("my_old_string_field2_modified")

doc2_with_version2.save(callback=self.stop)
doc2_with_version2 = self.wait()

# After saving the new version of the document it should stay the way it was designed to be
expect(doc2_with_version2.new_element).to_equal("my_new_string_field2")

def test_can_query_by_elem_match(self):
class ElemMatchDocument(Document):
items = ListField(IntField())
Expand Down

0 comments on commit e75fd58

Please sign in to comment.