adding column delete on save
This commit is contained in:
@@ -12,6 +12,7 @@ class BaseValueManager(object):
|
|||||||
self.initial_value = value
|
self.initial_value = value
|
||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
|
@property
|
||||||
def deleted(self):
|
def deleted(self):
|
||||||
return self.value is None and self.initial_value is not None
|
return self.value is None and self.initial_value is not None
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class BaseModel(object):
|
|||||||
value_mngr = column.value_manager(self, column, values.get(name, None))
|
value_mngr = column.value_manager(self, column, values.get(name, None))
|
||||||
self._values[name] = value_mngr
|
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
|
@classmethod
|
||||||
def column_family_name(cls):
|
def column_family_name(cls):
|
||||||
@@ -75,13 +75,16 @@ class ModelMetaClass(type):
|
|||||||
def __new__(cls, name, bases, attrs):
|
def __new__(cls, name, bases, attrs):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
#move column definitions into _columns dict
|
#move column definitions into columns dict
|
||||||
#and set default column names
|
#and set default column names
|
||||||
_columns = OrderedDict()
|
columns = OrderedDict()
|
||||||
|
primary_keys = OrderedDict()
|
||||||
pk_name = None
|
pk_name = None
|
||||||
|
|
||||||
def _transform_column(col_name, col_obj):
|
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)
|
col_obj.set_column_name(col_name)
|
||||||
#set properties
|
#set properties
|
||||||
_get = lambda self: self._values[col_name].getval()
|
_get = lambda self: self._values[col_name].getval()
|
||||||
@@ -112,7 +115,7 @@ class ModelMetaClass(type):
|
|||||||
|
|
||||||
#check for duplicate column names
|
#check for duplicate column names
|
||||||
col_names = set()
|
col_names = set()
|
||||||
for k,v in _columns.items():
|
for v in columns.values():
|
||||||
if v.db_field_name in col_names:
|
if v.db_field_name in col_names:
|
||||||
raise ModelException("{} defines the column {} more than once".format(name, v.db_field_name))
|
raise ModelException("{} defines the column {} more than once".format(name, v.db_field_name))
|
||||||
col_names.add(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
|
#create db_name -> model name map for loading
|
||||||
db_map = {}
|
db_map = {}
|
||||||
for field_name, col in _columns.items():
|
for field_name, col in columns.items():
|
||||||
db_map[col.db_field_name] = field_name
|
db_map[col.db_field_name] = field_name
|
||||||
|
|
||||||
#add management members to the class
|
#add management members to the class
|
||||||
attrs['_columns'] = _columns
|
attrs['_columns'] = columns
|
||||||
|
attrs['_primary_keys'] = primary_keys
|
||||||
attrs['_db_map'] = db_map
|
attrs['_db_map'] = db_map
|
||||||
attrs['_pk_name'] = pk_name
|
attrs['_pk_name'] = pk_name
|
||||||
attrs['_dynamic_columns'] = {}
|
attrs['_dynamic_columns'] = {}
|
||||||
|
|||||||
@@ -432,7 +432,25 @@ class QuerySet(object):
|
|||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
cur.execute(qs, field_values)
|
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):
|
def create(self, **kwargs):
|
||||||
return self.model(**kwargs).save()
|
return self.model(**kwargs).save()
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from cqlengine import columns
|
|||||||
class TestModel(Model):
|
class TestModel(Model):
|
||||||
count = columns.Integer()
|
count = columns.Integer()
|
||||||
text = columns.Text()
|
text = columns.Text()
|
||||||
|
|
||||||
class TestModelIO(BaseCassEngTestCase):
|
class TestModelIO(BaseCassEngTestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -54,11 +54,6 @@ class TestModelIO(BaseCassEngTestCase):
|
|||||||
tm2 = TestModel.objects(id=tm.pk).first()
|
tm2 = TestModel.objects(id=tm.pk).first()
|
||||||
self.assertIsNone(tm2)
|
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):
|
def test_column_deleting_works_properly(self):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -78,16 +78,6 @@ class TestQuerySetOperation(BaseCassEngTestCase):
|
|||||||
query2 = query1.filter(expected_result__gte=1)
|
query2 = query1.filter(expected_result__gte=1)
|
||||||
assert len(query2._where) == 2
|
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):
|
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
|
Tests that calling all on a queryset with previously defined filters returns a queryset with no filters
|
||||||
|
|||||||
Reference in New Issue
Block a user