adding single instance delete method and supporting unit test
adding column type stubs updating readme
This commit is contained in:
12
README.md
12
README.md
@@ -1,16 +1,22 @@
|
||||
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
|
||||
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
|
||||
* 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
|
||||
* return None when row isn't found in find()
|
||||
* tests
|
||||
* query functionality
|
||||
* nice column and model class __repr__
|
||||
|
||||
|
||||
|
||||
@@ -106,6 +106,9 @@ class Integer(BaseColumn):
|
||||
|
||||
class DateTime(BaseColumn):
|
||||
db_type = 'timestamp'
|
||||
def __init__(self, **kwargs):
|
||||
super(DateTime, self).__init__(**kwargs)
|
||||
raise NotImplementedError
|
||||
|
||||
class UUID(BaseColumn):
|
||||
"""
|
||||
@@ -153,4 +156,23 @@ class Float(BaseColumn):
|
||||
class Decimal(BaseColumn):
|
||||
db_type = 'decimal'
|
||||
#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
|
||||
|
||||
@@ -21,17 +21,20 @@ class Manager(object):
|
||||
#trim to less than 48 characters or cassandra will complain
|
||||
cf_name = cf_name[-48:]
|
||||
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):
|
||||
"""
|
||||
Returns the row corresponding to the primary key value given
|
||||
"""
|
||||
values = QuerySet(self.model).find(pk)
|
||||
if values is None: return
|
||||
|
||||
#change the column names to model names
|
||||
#in case they are different
|
||||
field_dict = {}
|
||||
@@ -55,6 +58,10 @@ class Manager(object):
|
||||
def create(self, **kwargs):
|
||||
return self.model(**kwargs).save()
|
||||
|
||||
def delete(self, **kwargs):
|
||||
pass
|
||||
|
||||
#----single instance methods----
|
||||
def _save_instance(self, instance):
|
||||
"""
|
||||
The business end of save, this is called by the models
|
||||
@@ -63,18 +70,15 @@ class Manager(object):
|
||||
"""
|
||||
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):
|
||||
QuerySet(self.model)._create_column_family()
|
||||
|
||||
def _delete_column_family(self):
|
||||
QuerySet(self.model)._delete_column_family()
|
||||
|
||||
def delete(self, **kwargs):
|
||||
pass
|
||||
|
||||
def __call__(self, **kwargs):
|
||||
"""
|
||||
filter shortcut
|
||||
"""
|
||||
return self.filter(**kwargs)
|
||||
|
||||
|
||||
@@ -65,7 +65,8 @@ class BaseModel(object):
|
||||
return self
|
||||
|
||||
def delete(self):
|
||||
pass
|
||||
""" Deletes this instance """
|
||||
self.objects._delete_instance(self)
|
||||
|
||||
|
||||
class ModelMetaClass(type):
|
||||
|
||||
@@ -42,7 +42,7 @@ class QuerySet(object):
|
||||
"""
|
||||
cur = self._cursor
|
||||
values = cur.fetchone()
|
||||
if values is None: return None
|
||||
if values is None: return
|
||||
names = [i[0] for i in cur.description]
|
||||
value_dict = dict(zip(names, values))
|
||||
return value_dict
|
||||
@@ -64,15 +64,12 @@ class QuerySet(object):
|
||||
return QuerySet(self.model, query_args=qargs)
|
||||
|
||||
def exclude(self, **kwargs):
|
||||
"""
|
||||
Need to invert the logic for all kwargs
|
||||
"""
|
||||
""" Need to invert the logic for all kwargs """
|
||||
pass
|
||||
|
||||
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):
|
||||
"""
|
||||
@@ -128,6 +125,23 @@ class QuerySet(object):
|
||||
cur = conn.cursor()
|
||||
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):
|
||||
#construct query string
|
||||
qs = ['CREATE TABLE {}'.format(self.column_family_name)]
|
||||
|
||||
@@ -38,6 +38,15 @@ class TestModelIO(BaseCassEngTestCase):
|
||||
tm2 = TestModel.objects.find(tm.pk)
|
||||
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):
|
||||
"""
|
||||
Tests that nullable columns save without any trouble
|
||||
|
||||
Reference in New Issue
Block a user