fixed #67 (validation on keyname typos) #66 (removed defaults on columns) and #57 and removed autoid
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
CHANGELOG
|
||||
|
||||
0.4.0
|
||||
* removed default values from all column types
|
||||
* explicit primary key is required (automatic id removed)
|
||||
|
||||
0.3.3
|
||||
* added abstract base class models
|
||||
|
||||
|
||||
@@ -236,9 +236,6 @@ class Integer(Column):
|
||||
class DateTime(Column):
|
||||
db_type = 'timestamp'
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(DateTime, self).__init__(**kwargs)
|
||||
|
||||
def to_python(self, value):
|
||||
if isinstance(value, datetime):
|
||||
return value
|
||||
@@ -265,8 +262,6 @@ class DateTime(Column):
|
||||
class Date(Column):
|
||||
db_type = 'timestamp'
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(Date, self).__init__(**kwargs)
|
||||
|
||||
def to_python(self, value):
|
||||
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}')
|
||||
|
||||
def __init__(self, default=lambda:uuid4(), **kwargs):
|
||||
super(UUID, self).__init__(default=default, **kwargs)
|
||||
|
||||
def validate(self, value):
|
||||
val = super(UUID, self).validate(value)
|
||||
if val is None: return
|
||||
@@ -319,10 +311,6 @@ class TimeUUID(UUID):
|
||||
|
||||
db_type = 'timeuuid'
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
kwargs.setdefault('default', lambda: uuid1())
|
||||
super(TimeUUID, self).__init__(**kwargs)
|
||||
|
||||
class Boolean(Column):
|
||||
db_type = 'boolean'
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ from collections import OrderedDict
|
||||
import re
|
||||
|
||||
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 DoesNotExist as _DoesNotExist
|
||||
from cqlengine.query import MultipleObjectsReturned as _MultipleObjectsReturned
|
||||
@@ -66,6 +66,11 @@ class BaseModel(object):
|
||||
|
||||
def __init__(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():
|
||||
value = values.get(name, None)
|
||||
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
|
||||
if not is_abstract and not any([v.primary_key for k,v in column_definitions]):
|
||||
k,v = 'id', columns.UUID(primary_key=True)
|
||||
column_definitions = [(k,v)] + column_definitions
|
||||
raise ModelDefinitionException("At least 1 primary key is required.")
|
||||
|
||||
has_partition_keys = any(v.partition_key for (k, v) in column_definitions)
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ from datetime import datetime, timedelta
|
||||
from datetime import date
|
||||
from datetime import tzinfo
|
||||
from decimal import Decimal as D
|
||||
from uuid import uuid4, uuid1
|
||||
from cqlengine import ValidationError
|
||||
|
||||
from cqlengine.tests.base import BaseCassEngTestCase
|
||||
@@ -119,7 +120,7 @@ class TestDecimal(BaseCassEngTestCase):
|
||||
class TestTimeUUID(BaseCassEngTestCase):
|
||||
class TimeUUIDTest(Model):
|
||||
test_id = Integer(primary_key=True)
|
||||
timeuuid = TimeUUID()
|
||||
timeuuid = TimeUUID(default=uuid1())
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@@ -132,6 +133,10 @@ class TestTimeUUID(BaseCassEngTestCase):
|
||||
delete_table(cls.TimeUUIDTest)
|
||||
|
||||
def test_timeuuid_io(self):
|
||||
"""
|
||||
ensures that
|
||||
:return:
|
||||
"""
|
||||
t0 = self.TimeUUIDTest.create(test_id=0)
|
||||
t1 = self.TimeUUIDTest.get(test_id=0)
|
||||
|
||||
@@ -139,8 +144,8 @@ class TestTimeUUID(BaseCassEngTestCase):
|
||||
|
||||
class TestInteger(BaseCassEngTestCase):
|
||||
class IntegerTest(Model):
|
||||
test_id = UUID(primary_key=True)
|
||||
value = Integer(default=0)
|
||||
test_id = UUID(primary_key=True, default=lambda:uuid4())
|
||||
value = Integer(default=0, required=True)
|
||||
|
||||
def test_default_zero_fields_validate(self):
|
||||
""" 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)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
from uuid import uuid4
|
||||
from cqlengine.query import QueryException
|
||||
from cqlengine.tests.base import BaseCassEngTestCase
|
||||
|
||||
from cqlengine.exceptions import ModelException, CQLEngineException
|
||||
from cqlengine.models import Model
|
||||
from cqlengine.models import Model, ModelDefinitionException
|
||||
from cqlengine import columns
|
||||
import cqlengine
|
||||
|
||||
@@ -18,6 +19,7 @@ class TestModelClassFunction(BaseCassEngTestCase):
|
||||
"""
|
||||
|
||||
class TestModel(Model):
|
||||
id = columns.UUID(primary_key=True, default=lambda:uuid4())
|
||||
text = columns.Text()
|
||||
|
||||
#check class attibutes
|
||||
@@ -38,6 +40,7 @@ class TestModelClassFunction(BaseCassEngTestCase):
|
||||
-the db_map allows columns
|
||||
"""
|
||||
class WildDBNames(Model):
|
||||
id = columns.UUID(primary_key=True, default=lambda:uuid4())
|
||||
content = columns.Text(db_field='words_and_whatnot')
|
||||
numbers = columns.Integer(db_field='integers_etc')
|
||||
|
||||
@@ -61,17 +64,26 @@ class TestModelClassFunction(BaseCassEngTestCase):
|
||||
"""
|
||||
|
||||
class Stuff(Model):
|
||||
id = columns.UUID(primary_key=True, default=lambda:uuid4())
|
||||
words = columns.Text()
|
||||
content = columns.Text()
|
||||
numbers = columns.Integer()
|
||||
|
||||
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):
|
||||
"""
|
||||
Tests that instance value managers are isolated from other instances
|
||||
"""
|
||||
class Stuff(Model):
|
||||
id = columns.UUID(primary_key=True, default=lambda:uuid4())
|
||||
num = columns.Integer()
|
||||
|
||||
inst1 = Stuff(num=5)
|
||||
@@ -86,6 +98,7 @@ class TestModelClassFunction(BaseCassEngTestCase):
|
||||
Tests that fields defined on the super class are inherited properly
|
||||
"""
|
||||
class TestModel(Model):
|
||||
id = columns.UUID(primary_key=True, default=lambda:uuid4())
|
||||
text = columns.Text()
|
||||
|
||||
class InheritedModel(TestModel):
|
||||
@@ -124,6 +137,7 @@ class TestModelClassFunction(BaseCassEngTestCase):
|
||||
Test compound partition key definition
|
||||
"""
|
||||
class ModelWithPartitionKeys(cqlengine.Model):
|
||||
id = columns.UUID(primary_key=True, default=lambda:uuid4())
|
||||
c1 = cqlengine.Text(primary_key=True)
|
||||
p1 = 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):
|
||||
""" Tests that columns that can be deleted have the del attribute """
|
||||
class DelModel(Model):
|
||||
id = columns.UUID(primary_key=True, default=lambda:uuid4())
|
||||
key = columns.Integer(primary_key=True)
|
||||
data = columns.Integer(required=False)
|
||||
|
||||
@@ -156,9 +171,10 @@ class TestModelClassFunction(BaseCassEngTestCase):
|
||||
""" Tests that DoesNotExist exceptions are not the same exception between models """
|
||||
|
||||
class Model1(Model):
|
||||
pass
|
||||
id = columns.UUID(primary_key=True, default=lambda:uuid4())
|
||||
|
||||
class Model2(Model):
|
||||
pass
|
||||
id = columns.UUID(primary_key=True, default=lambda:uuid4())
|
||||
|
||||
try:
|
||||
raise Model1.DoesNotExist
|
||||
@@ -171,7 +187,8 @@ class TestModelClassFunction(BaseCassEngTestCase):
|
||||
def test_does_not_exist_inherits_from_superclass(self):
|
||||
""" Tests that a DoesNotExist exception can be caught by it's parent class DoesNotExist """
|
||||
class Model1(Model):
|
||||
pass
|
||||
id = columns.UUID(primary_key=True, default=lambda:uuid4())
|
||||
|
||||
class Model2(Model1):
|
||||
pass
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from unittest import skip
|
||||
from uuid import uuid4
|
||||
from cqlengine.tests.base import BaseCassEngTestCase
|
||||
|
||||
from cqlengine.management import create_table
|
||||
@@ -7,6 +8,7 @@ from cqlengine.models import Model
|
||||
from cqlengine import columns
|
||||
|
||||
class TestModel(Model):
|
||||
id = columns.UUID(primary_key=True, default=lambda:uuid4())
|
||||
count = columns.Integer()
|
||||
text = columns.Text(required=False)
|
||||
|
||||
|
||||
@@ -8,10 +8,18 @@ from cqlengine.models import Model
|
||||
from cqlengine import columns
|
||||
|
||||
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 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):
|
||||
|
||||
@classmethod
|
||||
@@ -34,6 +42,8 @@ class TestModelIO(BaseCassEngTestCase):
|
||||
for cname in tm._columns.keys():
|
||||
self.assertEquals(getattr(tm, cname), getattr(tm2, cname))
|
||||
|
||||
|
||||
|
||||
def test_model_updating_works_properly(self):
|
||||
"""
|
||||
Tests that subsequent saves after initial model creation work
|
||||
|
||||
Reference in New Issue
Block a user