fixed #67 (validation on keyname typos) #66 (removed defaults on columns) and #57 and removed autoid

This commit is contained in:
Jon Haddad
2013-06-14 17:52:13 -07:00
parent 35811d1fab
commit 4a977005f3
7 changed files with 69 additions and 33 deletions

View File

@@ -1,5 +1,9 @@
CHANGELOG CHANGELOG
0.4.0
* removed default values from all column types
* explicit primary key is required (automatic id removed)
0.3.3 0.3.3
* added abstract base class models * added abstract base class models

View File

@@ -236,9 +236,6 @@ class Integer(Column):
class DateTime(Column): class DateTime(Column):
db_type = 'timestamp' db_type = 'timestamp'
def __init__(self, **kwargs):
super(DateTime, self).__init__(**kwargs)
def to_python(self, value): def to_python(self, value):
if isinstance(value, datetime): if isinstance(value, datetime):
return value return value
@@ -265,8 +262,6 @@ class DateTime(Column):
class Date(Column): class Date(Column):
db_type = 'timestamp' db_type = 'timestamp'
def __init__(self, **kwargs):
super(Date, self).__init__(**kwargs)
def to_python(self, value): def to_python(self, value):
if isinstance(value, datetime): if isinstance(value, datetime):
@@ -294,9 +289,6 @@ class UUID(Column):
re_uuid = re.compile(r'[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') re_uuid = re.compile(r'[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')
def __init__(self, default=lambda:uuid4(), **kwargs):
super(UUID, self).__init__(default=default, **kwargs)
def validate(self, value): def validate(self, value):
val = super(UUID, self).validate(value) val = super(UUID, self).validate(value)
if val is None: return if val is None: return
@@ -319,10 +311,6 @@ class TimeUUID(UUID):
db_type = 'timeuuid' db_type = 'timeuuid'
def __init__(self, **kwargs):
kwargs.setdefault('default', lambda: uuid1())
super(TimeUUID, self).__init__(**kwargs)
class Boolean(Column): class Boolean(Column):
db_type = 'boolean' db_type = 'boolean'

View File

@@ -2,7 +2,7 @@ from collections import OrderedDict
import re import re
from cqlengine import columns from cqlengine import columns
from cqlengine.exceptions import ModelException, CQLEngineException from cqlengine.exceptions import ModelException, CQLEngineException, ValidationError
from cqlengine.query import QuerySet, DMLQuery from cqlengine.query import QuerySet, DMLQuery
from cqlengine.query import DoesNotExist as _DoesNotExist from cqlengine.query import DoesNotExist as _DoesNotExist
from cqlengine.query import MultipleObjectsReturned as _MultipleObjectsReturned from cqlengine.query import MultipleObjectsReturned as _MultipleObjectsReturned
@@ -66,6 +66,11 @@ class BaseModel(object):
def __init__(self, **values): def __init__(self, **values):
self._values = {} self._values = {}
extra_columns = set(values.keys()) - set(self._columns.keys())
if extra_columns:
raise ValidationError("Incorrect columns passed: {}".format(extra_columns))
for name, column in self._columns.items(): for name, column in self._columns.items():
value = values.get(name, None) value = values.get(name, None)
if value is not None: value = column.to_python(value) if value is not None: value = column.to_python(value)
@@ -226,8 +231,7 @@ class ModelMetaClass(type):
#prepend primary key if one hasn't been defined #prepend primary key if one hasn't been defined
if not is_abstract and not any([v.primary_key for k,v in column_definitions]): if not is_abstract and not any([v.primary_key for k,v in column_definitions]):
k,v = 'id', columns.UUID(primary_key=True) raise ModelDefinitionException("At least 1 primary key is required.")
column_definitions = [(k,v)] + column_definitions
has_partition_keys = any(v.partition_key for (k, v) in column_definitions) has_partition_keys = any(v.partition_key for (k, v) in column_definitions)

View File

@@ -3,6 +3,7 @@ from datetime import datetime, timedelta
from datetime import date from datetime import date
from datetime import tzinfo from datetime import tzinfo
from decimal import Decimal as D from decimal import Decimal as D
from uuid import uuid4, uuid1
from cqlengine import ValidationError from cqlengine import ValidationError
from cqlengine.tests.base import BaseCassEngTestCase from cqlengine.tests.base import BaseCassEngTestCase
@@ -119,7 +120,7 @@ class TestDecimal(BaseCassEngTestCase):
class TestTimeUUID(BaseCassEngTestCase): class TestTimeUUID(BaseCassEngTestCase):
class TimeUUIDTest(Model): class TimeUUIDTest(Model):
test_id = Integer(primary_key=True) test_id = Integer(primary_key=True)
timeuuid = TimeUUID() timeuuid = TimeUUID(default=uuid1())
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
@@ -132,6 +133,10 @@ class TestTimeUUID(BaseCassEngTestCase):
delete_table(cls.TimeUUIDTest) delete_table(cls.TimeUUIDTest)
def test_timeuuid_io(self): def test_timeuuid_io(self):
"""
ensures that
:return:
"""
t0 = self.TimeUUIDTest.create(test_id=0) t0 = self.TimeUUIDTest.create(test_id=0)
t1 = self.TimeUUIDTest.get(test_id=0) t1 = self.TimeUUIDTest.get(test_id=0)
@@ -139,8 +144,8 @@ class TestTimeUUID(BaseCassEngTestCase):
class TestInteger(BaseCassEngTestCase): class TestInteger(BaseCassEngTestCase):
class IntegerTest(Model): class IntegerTest(Model):
test_id = UUID(primary_key=True) test_id = UUID(primary_key=True, default=lambda:uuid4())
value = Integer(default=0) value = Integer(default=0, required=True)
def test_default_zero_fields_validate(self): def test_default_zero_fields_validate(self):
""" Tests that integer columns with a default value of 0 validate """ """ Tests that integer columns with a default value of 0 validate """
@@ -190,7 +195,13 @@ class TestText(BaseCassEngTestCase):
class TestExtraFieldsRaiseException(BaseCassEngTestCase):
class TestModel(Model):
id = UUID(primary_key=True, default=uuid4)
def test_extra_field(self):
with self.assertRaises(ValidationError):
self.TestModel.create(bacon=5000)

View File

@@ -1,8 +1,9 @@
from uuid import uuid4
from cqlengine.query import QueryException from cqlengine.query import QueryException
from cqlengine.tests.base import BaseCassEngTestCase from cqlengine.tests.base import BaseCassEngTestCase
from cqlengine.exceptions import ModelException, CQLEngineException from cqlengine.exceptions import ModelException, CQLEngineException
from cqlengine.models import Model from cqlengine.models import Model, ModelDefinitionException
from cqlengine import columns from cqlengine import columns
import cqlengine import cqlengine
@@ -18,6 +19,7 @@ class TestModelClassFunction(BaseCassEngTestCase):
""" """
class TestModel(Model): class TestModel(Model):
id = columns.UUID(primary_key=True, default=lambda:uuid4())
text = columns.Text() text = columns.Text()
#check class attibutes #check class attibutes
@@ -38,6 +40,7 @@ class TestModelClassFunction(BaseCassEngTestCase):
-the db_map allows columns -the db_map allows columns
""" """
class WildDBNames(Model): class WildDBNames(Model):
id = columns.UUID(primary_key=True, default=lambda:uuid4())
content = columns.Text(db_field='words_and_whatnot') content = columns.Text(db_field='words_and_whatnot')
numbers = columns.Integer(db_field='integers_etc') numbers = columns.Integer(db_field='integers_etc')
@@ -61,17 +64,26 @@ class TestModelClassFunction(BaseCassEngTestCase):
""" """
class Stuff(Model): class Stuff(Model):
id = columns.UUID(primary_key=True, default=lambda:uuid4())
words = columns.Text() words = columns.Text()
content = columns.Text() content = columns.Text()
numbers = columns.Integer() numbers = columns.Integer()
self.assertEquals(Stuff._columns.keys(), ['id', 'words', 'content', 'numbers']) self.assertEquals(Stuff._columns.keys(), ['id', 'words', 'content', 'numbers'])
def test_exception_raised_when_creating_class_without_pk(self):
with self.assertRaises(ModelDefinitionException):
class TestModel(Model):
count = columns.Integer()
text = columns.Text(required=False)
def test_value_managers_are_keeping_model_instances_isolated(self): def test_value_managers_are_keeping_model_instances_isolated(self):
""" """
Tests that instance value managers are isolated from other instances Tests that instance value managers are isolated from other instances
""" """
class Stuff(Model): class Stuff(Model):
id = columns.UUID(primary_key=True, default=lambda:uuid4())
num = columns.Integer() num = columns.Integer()
inst1 = Stuff(num=5) inst1 = Stuff(num=5)
@@ -86,6 +98,7 @@ class TestModelClassFunction(BaseCassEngTestCase):
Tests that fields defined on the super class are inherited properly Tests that fields defined on the super class are inherited properly
""" """
class TestModel(Model): class TestModel(Model):
id = columns.UUID(primary_key=True, default=lambda:uuid4())
text = columns.Text() text = columns.Text()
class InheritedModel(TestModel): class InheritedModel(TestModel):
@@ -124,6 +137,7 @@ class TestModelClassFunction(BaseCassEngTestCase):
Test compound partition key definition Test compound partition key definition
""" """
class ModelWithPartitionKeys(cqlengine.Model): class ModelWithPartitionKeys(cqlengine.Model):
id = columns.UUID(primary_key=True, default=lambda:uuid4())
c1 = cqlengine.Text(primary_key=True) c1 = cqlengine.Text(primary_key=True)
p1 = cqlengine.Text(partition_key=True) p1 = cqlengine.Text(partition_key=True)
p2 = cqlengine.Text(partition_key=True) p2 = cqlengine.Text(partition_key=True)
@@ -144,6 +158,7 @@ class TestModelClassFunction(BaseCassEngTestCase):
def test_del_attribute_is_assigned_properly(self): def test_del_attribute_is_assigned_properly(self):
""" Tests that columns that can be deleted have the del attribute """ """ Tests that columns that can be deleted have the del attribute """
class DelModel(Model): class DelModel(Model):
id = columns.UUID(primary_key=True, default=lambda:uuid4())
key = columns.Integer(primary_key=True) key = columns.Integer(primary_key=True)
data = columns.Integer(required=False) data = columns.Integer(required=False)
@@ -156,9 +171,10 @@ class TestModelClassFunction(BaseCassEngTestCase):
""" Tests that DoesNotExist exceptions are not the same exception between models """ """ Tests that DoesNotExist exceptions are not the same exception between models """
class Model1(Model): class Model1(Model):
pass id = columns.UUID(primary_key=True, default=lambda:uuid4())
class Model2(Model): class Model2(Model):
pass id = columns.UUID(primary_key=True, default=lambda:uuid4())
try: try:
raise Model1.DoesNotExist raise Model1.DoesNotExist
@@ -171,7 +187,8 @@ class TestModelClassFunction(BaseCassEngTestCase):
def test_does_not_exist_inherits_from_superclass(self): def test_does_not_exist_inherits_from_superclass(self):
""" Tests that a DoesNotExist exception can be caught by it's parent class DoesNotExist """ """ Tests that a DoesNotExist exception can be caught by it's parent class DoesNotExist """
class Model1(Model): class Model1(Model):
pass id = columns.UUID(primary_key=True, default=lambda:uuid4())
class Model2(Model1): class Model2(Model1):
pass pass

View File

@@ -1,4 +1,5 @@
from unittest import skip from unittest import skip
from uuid import uuid4
from cqlengine.tests.base import BaseCassEngTestCase from cqlengine.tests.base import BaseCassEngTestCase
from cqlengine.management import create_table from cqlengine.management import create_table
@@ -7,6 +8,7 @@ from cqlengine.models import Model
from cqlengine import columns from cqlengine import columns
class TestModel(Model): class TestModel(Model):
id = columns.UUID(primary_key=True, default=lambda:uuid4())
count = columns.Integer() count = columns.Integer()
text = columns.Text(required=False) text = columns.Text(required=False)

View File

@@ -8,10 +8,18 @@ from cqlengine.models import Model
from cqlengine import columns from cqlengine import columns
class TestModel(Model): class TestModel(Model):
id = columns.UUID(primary_key=True, default=lambda:uuid4())
count = columns.Integer() count = columns.Integer()
text = columns.Text(required=False) text = columns.Text(required=False)
a_bool = columns.Boolean(default=False) a_bool = columns.Boolean(default=False)
class TestModel(Model):
id = columns.UUID(primary_key=True, default=lambda:uuid4())
count = columns.Integer()
text = columns.Text(required=False)
a_bool = columns.Boolean(default=False)
class TestModelIO(BaseCassEngTestCase): class TestModelIO(BaseCassEngTestCase):
@classmethod @classmethod
@@ -34,6 +42,8 @@ class TestModelIO(BaseCassEngTestCase):
for cname in tm._columns.keys(): for cname in tm._columns.keys():
self.assertEquals(getattr(tm, cname), getattr(tm2, cname)) self.assertEquals(getattr(tm, cname), getattr(tm2, cname))
def test_model_updating_works_properly(self): def test_model_updating_works_properly(self):
""" """
Tests that subsequent saves after initial model creation work Tests that subsequent saves after initial model creation work