From 2cbf582b0dfc3d05c8494506c54386efd68f1832 Mon Sep 17 00:00:00 2001 From: Blake Eggleston Date: Sat, 24 Nov 2012 17:33:14 -0800 Subject: [PATCH] adding column delete on save --- cqlengine/columns.py | 1 + cqlengine/models.py | 18 +++++++++++------- cqlengine/query.py | 20 +++++++++++++++++++- cqlengine/tests/model/test_model_io.py | 7 +------ cqlengine/tests/query/test_queryset.py | 10 ---------- 5 files changed, 32 insertions(+), 24 deletions(-) diff --git a/cqlengine/columns.py b/cqlengine/columns.py index a1ba0a3c..9236d44e 100644 --- a/cqlengine/columns.py +++ b/cqlengine/columns.py @@ -12,6 +12,7 @@ class BaseValueManager(object): self.initial_value = value self.value = value + @property def deleted(self): return self.value is None and self.initial_value is not None diff --git a/cqlengine/models.py b/cqlengine/models.py index 9111b759..3893bb9e 100644 --- a/cqlengine/models.py +++ b/cqlengine/models.py @@ -24,7 +24,7 @@ class BaseModel(object): value_mngr = column.value_manager(self, column, values.get(name, None)) self._values[name] = value_mngr - #TODO: note any deferred or only fields so they're not deleted + #TODO: note any absent fields so they're not deleted @classmethod def column_family_name(cls): @@ -75,13 +75,16 @@ class ModelMetaClass(type): def __new__(cls, name, bases, attrs): """ """ - #move column definitions into _columns dict + #move column definitions into columns dict #and set default column names - _columns = OrderedDict() + columns = OrderedDict() + primary_keys = OrderedDict() pk_name = None def _transform_column(col_name, col_obj): - _columns[col_name] = col_obj + columns[col_name] = col_obj + if col_obj.primary_key: + primary_keys[col_name] = col_obj col_obj.set_column_name(col_name) #set properties _get = lambda self: self._values[col_name].getval() @@ -112,7 +115,7 @@ class ModelMetaClass(type): #check for duplicate column names col_names = set() - for k,v in _columns.items(): + for v in columns.values(): if v.db_field_name in col_names: raise ModelException("{} defines the column {} more than once".format(name, v.db_field_name)) col_names.add(v.db_field_name) @@ -128,11 +131,12 @@ class ModelMetaClass(type): #create db_name -> model name map for loading db_map = {} - for field_name, col in _columns.items(): + for field_name, col in columns.items(): db_map[col.db_field_name] = field_name #add management members to the class - attrs['_columns'] = _columns + attrs['_columns'] = columns + attrs['_primary_keys'] = primary_keys attrs['_db_map'] = db_map attrs['_pk_name'] = pk_name attrs['_dynamic_columns'] = {} diff --git a/cqlengine/query.py b/cqlengine/query.py index 7efd1929..e6cccc9f 100644 --- a/cqlengine/query.py +++ b/cqlengine/query.py @@ -432,7 +432,25 @@ class QuerySet(object): cur = conn.cursor() cur.execute(qs, field_values) - #TODO: delete deleted / nulled fields + #TODO: delete deleted / nulled columns + deleted = [k for k,v in instance._values.items() if v.deleted] + if deleted: + import ipdb; ipdb.set_trace() + del_fields = [self.model._columns[f] for f in deleted] + del_fields = [f.db_field_name for f in del_fields if not f.primary_key] + pks = self.model._primary_keys + qs = ['DELETE {}'.format(', '.join(del_fields))] + qs += ['FROM {}'.format(self.column_family_name)] + qs += ['WHERE'] + eq = lambda col: '{0} = :{0}'.format(v.db_field_name) + qs += [' AND '.join([eq(f) for f in pks.values()])] + qs = ' '.join(qs) + + pk_dict = dict([(v.db_field_name, getattr(instance, k)) for k,v in pks.items()]) + cur.execute(qs, pk_dict) + + + def create(self, **kwargs): return self.model(**kwargs).save() diff --git a/cqlengine/tests/model/test_model_io.py b/cqlengine/tests/model/test_model_io.py index cf43f96d..09a72809 100644 --- a/cqlengine/tests/model/test_model_io.py +++ b/cqlengine/tests/model/test_model_io.py @@ -10,7 +10,7 @@ from cqlengine import columns class TestModel(Model): count = columns.Integer() text = columns.Text() - + class TestModelIO(BaseCassEngTestCase): @classmethod @@ -54,11 +54,6 @@ class TestModelIO(BaseCassEngTestCase): tm2 = TestModel.objects(id=tm.pk).first() self.assertIsNone(tm2) - def test_nullable_columns_are_saved_properly(self): - """ - Tests that nullable columns save without any trouble - """ - def test_column_deleting_works_properly(self): """ """ diff --git a/cqlengine/tests/query/test_queryset.py b/cqlengine/tests/query/test_queryset.py index 256e6816..b3c1449a 100644 --- a/cqlengine/tests/query/test_queryset.py +++ b/cqlengine/tests/query/test_queryset.py @@ -78,16 +78,6 @@ class TestQuerySetOperation(BaseCassEngTestCase): query2 = query1.filter(expected_result__gte=1) assert len(query2._where) == 2 - def test_queryset_slicing(self): - """ - Check that the limit and start is implemented as iterator slices - """ - - def test_proper_delete_behavior(self): - """ - Tests that deleting the contents of a queryset works properly - """ - def test_the_all_method_clears_where_filter(self): """ Tests that calling all on a queryset with previously defined filters returns a queryset with no filters