adding single instance delete method and supporting unit test

adding column type stubs
updating readme
This commit is contained in:
Blake Eggleston
2012-11-11 11:43:05 -08:00
parent b6042ac57a
commit 4764b492eb
6 changed files with 80 additions and 24 deletions

View File

@@ -1,16 +1,22 @@
cassandraengine cassandraengine
=============== ===============
Django ORM / Mongoengine style ORM for Cassandra Python Cassandra ORM in the style of django / mongoengine
In it's current state you can define column families, create and delete column families In it's current state you can define column families, create and delete column families
based on your model definiteions, save models and retrieve models by their primary keys. based on your model definiteions, save models and retrieve models by their primary keys.
That's about it. Also, there are only 2 tests and the CQL stuff is very simplistic at this point. That's about it. Also, the CQL stuff is pretty simple at this point.
##TODO ##TODO
* Complex queries (class Q(object))
* Match column names to mongoengine field names?
* mongoengine fields? URLField, EmbeddedDocument, ListField, DictField
* column ttl?
* ForeignKey/DBRef fields?
* dynamic column support * dynamic column support
* return None when row isn't found in find()
* tests * tests
* query functionality * query functionality
* nice column and model class __repr__ * nice column and model class __repr__

View File

@@ -106,6 +106,9 @@ class Integer(BaseColumn):
class DateTime(BaseColumn): class DateTime(BaseColumn):
db_type = 'timestamp' db_type = 'timestamp'
def __init__(self, **kwargs):
super(DateTime, self).__init__(**kwargs)
raise NotImplementedError
class UUID(BaseColumn): class UUID(BaseColumn):
""" """
@@ -153,4 +156,23 @@ class Float(BaseColumn):
class Decimal(BaseColumn): class Decimal(BaseColumn):
db_type = 'decimal' db_type = 'decimal'
#TODO: this #TODO: this
def __init__(self, **kwargs):
super(DateTime, self).__init__(**kwargs)
raise NotImplementedError
class Counter(BaseColumn):
def __init__(self, **kwargs):
super(DateTime, self).__init__(**kwargs)
raise NotImplementedError
#TODO: research supercolumns
#http://wiki.apache.org/cassandra/DataModel
class List(BaseColumn):
def __init__(self, **kwargs):
super(DateTime, self).__init__(**kwargs)
raise NotImplementedError
class Dict(BaseColumn):
def __init__(self, **kwargs):
super(DateTime, self).__init__(**kwargs)
raise NotImplementedError

View File

@@ -22,16 +22,19 @@ class Manager(object):
cf_name = cf_name[-48:] cf_name = cf_name[-48:]
return cf_name return cf_name
def column_family_definition(self): def __call__(self, **kwargs):
""" """
Generates a definition used for tale creation filter shortcut
""" """
return self.filter(**kwargs)
def find(self, pk): def find(self, pk):
""" """
Returns the row corresponding to the primary key value given Returns the row corresponding to the primary key value given
""" """
values = QuerySet(self.model).find(pk) values = QuerySet(self.model).find(pk)
if values is None: return
#change the column names to model names #change the column names to model names
#in case they are different #in case they are different
field_dict = {} field_dict = {}
@@ -55,6 +58,10 @@ class Manager(object):
def create(self, **kwargs): def create(self, **kwargs):
return self.model(**kwargs).save() return self.model(**kwargs).save()
def delete(self, **kwargs):
pass
#----single instance methods----
def _save_instance(self, instance): def _save_instance(self, instance):
""" """
The business end of save, this is called by the models The business end of save, this is called by the models
@@ -63,18 +70,15 @@ class Manager(object):
""" """
QuerySet(self.model).save(instance) QuerySet(self.model).save(instance)
def _delete_instance(self, instance):
"""
Deletes a single instance
"""
QuerySet(self.model).delete_instance(instance)
#----column family create/delete----
def _create_column_family(self): def _create_column_family(self):
QuerySet(self.model)._create_column_family() QuerySet(self.model)._create_column_family()
def _delete_column_family(self): def _delete_column_family(self):
QuerySet(self.model)._delete_column_family() QuerySet(self.model)._delete_column_family()
def delete(self, **kwargs):
pass
def __call__(self, **kwargs):
"""
filter shortcut
"""
return self.filter(**kwargs)

View File

@@ -65,7 +65,8 @@ class BaseModel(object):
return self return self
def delete(self): def delete(self):
pass """ Deletes this instance """
self.objects._delete_instance(self)
class ModelMetaClass(type): class ModelMetaClass(type):

View File

@@ -42,7 +42,7 @@ class QuerySet(object):
""" """
cur = self._cursor cur = self._cursor
values = cur.fetchone() values = cur.fetchone()
if values is None: return None if values is None: return
names = [i[0] for i in cur.description] names = [i[0] for i in cur.description]
value_dict = dict(zip(names, values)) value_dict = dict(zip(names, values))
return value_dict return value_dict
@@ -64,15 +64,12 @@ class QuerySet(object):
return QuerySet(self.model, query_args=qargs) return QuerySet(self.model, query_args=qargs)
def exclude(self, **kwargs): def exclude(self, **kwargs):
""" """ Need to invert the logic for all kwargs """
Need to invert the logic for all kwargs
"""
pass pass
def count(self): def count(self):
""" """ Returns the number of rows matched by this query """
Returns the number of rows matched by this query qs = 'SELECT COUNT(*) FROM {}'.format(self.column_family_name)
"""
def find(self, pk): def find(self, pk):
""" """
@@ -128,6 +125,23 @@ class QuerySet(object):
cur = conn.cursor() cur = conn.cursor()
cur.execute(qs, field_values) cur.execute(qs, field_values)
#----delete---
def delete(self):
"""
Deletes the contents of a query
"""
def delete_instance(self, instance):
""" Deletes one instance """
pk_name = self.model._pk_name
qs = ['DELETE FROM {}'.format(self.column_family_name)]
qs += ['WHERE {0}=:{0}'.format(pk_name)]
qs = ' '.join(qs)
conn = get_connection()
cur = conn.cursor()
cur.execute(qs, {pk_name:instance.pk})
def _create_column_family(self): def _create_column_family(self):
#construct query string #construct query string
qs = ['CREATE TABLE {}'.format(self.column_family_name)] qs = ['CREATE TABLE {}'.format(self.column_family_name)]

View File

@@ -38,6 +38,15 @@ class TestModelIO(BaseCassEngTestCase):
tm2 = TestModel.objects.find(tm.pk) tm2 = TestModel.objects.find(tm.pk)
self.assertEquals(tm.count, tm2.count) self.assertEquals(tm.count, tm2.count)
def test_model_deleting_works_properly(self):
"""
Tests that an instance's delete method deletes the instance
"""
tm = TestModel.objects.create(count=8, text='123456789')
tm.delete()
tm2 = TestModel.objects.find(tm.pk)
self.assertIsNone(tm2)
def test_nullable_columns_are_saved_properly(self): def test_nullable_columns_are_saved_properly(self):
""" """
Tests that nullable columns save without any trouble Tests that nullable columns save without any trouble