diff --git a/cassandra/cqlengine/columns.py b/cassandra/cqlengine/columns.py index 80b2e5c4..9e7c2cad 100644 --- a/cassandra/cqlengine/columns.py +++ b/cassandra/cqlengine/columns.py @@ -235,8 +235,6 @@ class Column(object): """ Converts python value into database value """ - if value is None and self.has_default: - return self.get_default() return value @property @@ -948,7 +946,16 @@ class Map(BaseContainerColumn): class UDTValueManager(BaseValueManager): @property def changed(self): - return self.value != self.previous_value or (self.value is not None and self.value.has_changed_fields()) + if self.explicit: + return self.value != self.previous_value + + default_value = self.column.get_default() + if not self.column._val_is_null(default_value): + return self.value != default_value + elif self.previous_value is None: + return not self.column._val_is_null(self.value) and self.value.has_changed_fields() + + return False def reset_previous_value(self): if self.value is not None: diff --git a/tests/integration/cqlengine/model/test_updates.py b/tests/integration/cqlengine/model/test_updates.py index c22668bc..2f966e7e 100644 --- a/tests/integration/cqlengine/model/test_updates.py +++ b/tests/integration/cqlengine/model/test_updates.py @@ -183,9 +183,11 @@ class ModelWithDefaultTests(BaseCassEngTestCase): def setUp(self): sync_table(ModelWithDefault) + sync_table(ModelWithDefaultCollection) def tearDown(self): drop_table(ModelWithDefault) + drop_table(ModelWithDefaultCollection) def test_value_override_with_default(self): """ @@ -309,28 +311,35 @@ class ModelWithDefaultTests(BaseCassEngTestCase): udt, udt_default = UDT(age=1, mf={6: 6}), UDT(age=1, mf={6: 6}) item = ModelWithDefaultCollection.create(id=1, mf={1: 1}, dummy=1, udt=udt, udt_default=udt_default).save() - self.assertEqual(ModelWithDefaultCollection.all().get()._as_dict(), + self.assertEqual(ModelWithDefaultCollection.objects.get(id=1)._as_dict(), {'id': 1, 'dummy': 1, 'mf': {1: 1}, "udt": udt, "udt_default": udt_default}) udt, udt_default = UDT(age=1, mf={5: 5}), UDT(age=1, mf={5: 5}) item.update(mf={2: 2}, udt=udt, udt_default=udt_default) - self.assertEqual(ModelWithDefaultCollection.all().get()._as_dict(), + self.assertEqual(ModelWithDefaultCollection.objects.get(id=1)._as_dict(), {'id': 1, 'dummy': 1, 'mf': {2: 2}, "udt": udt, "udt_default": udt_default}) udt, udt_default = UDT(age=1, mf=None), UDT(age=1, mf=None) expected_udt, expected_udt_default = UDT(age=1, mf={}), UDT(age=1, mf={}) item.update(mf=None, udt=udt, udt_default=udt_default) - self.assertEqual(ModelWithDefaultCollection.all().get()._as_dict(), + self.assertEqual(ModelWithDefaultCollection.objects.get(id=1)._as_dict(), {'id': 1, 'dummy': 1, 'mf': {}, "udt": expected_udt, "udt_default": expected_udt_default}) - udt_default = UDT(age=1, mf=None), UDT(age=1, mf={5:5}) - item = ModelWithDefaultCollection.create(id=2, dummy=2).save() - self.assertEqual(ModelWithDefaultCollection.all().get(id=2)._as_dict(), + udt_default = UDT(age=1, mf={2:2}, dummy_udt=42) + item = ModelWithDefaultCollection.create(id=2, dummy=2) + self.assertEqual(ModelWithDefaultCollection.objects.get(id=2)._as_dict(), {'id': 2, 'dummy': 2, 'mf': {2: 2}, "udt": None, "udt_default": udt_default}) udt, udt_default = UDT(age=1, mf={1: 1, 6: 6}), UDT(age=1, mf={1: 1, 6: 6}) item.update(mf={1: 1, 4: 4}, udt=udt, udt_default=udt_default) - self.assertEqual(ModelWithDefaultCollection.all().get(id=2)._as_dict(), + self.assertEqual(ModelWithDefaultCollection.objects.get(id=2)._as_dict(), {'id': 2, 'dummy': 2, 'mf': {1: 1, 4: 4}, "udt": udt, "udt_default": udt_default}) - drop_table(ModelWithDefaultCollection) + item.update(udt_default=None) + self.assertEqual(ModelWithDefaultCollection.objects.get(id=2)._as_dict(), + {'id': 2, 'dummy': 2, 'mf': {1: 1, 4: 4}, "udt": udt, "udt_default": None}) + + udt_default = UDT(age=1, mf={2:2}) + item.update(udt_default=udt_default) + self.assertEqual(ModelWithDefaultCollection.objects.get(id=2)._as_dict(), + {'id': 2, 'dummy': 2, 'mf': {1: 1, 4: 4}, "udt": udt, "udt_default": udt_default})