A ModelDefinitionException is now thrown from the metaclass at model definition time if the model contains a column whose name conflicts with a built-in attribute or method.
(See https://github.com/cqlengine/cqlengine/issues/193)
This commit is contained in:

committed by
Caleb Rackliffe

parent
aad7e3b648
commit
d075a487c7
@@ -649,9 +649,12 @@ class ModelMetaClass(type):
|
|||||||
|
|
||||||
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)
|
||||||
|
|
||||||
#TODO: check that the defined columns don't conflict with any of the Model API's existing attributes/methods
|
|
||||||
#transform column definitions
|
#transform column definitions
|
||||||
for k, v in column_definitions:
|
for k, v in column_definitions:
|
||||||
|
# don't allow a column with the same name as a built-in attribute or method
|
||||||
|
if k in BaseModel.__dict__:
|
||||||
|
raise ModelDefinitionException("column '{}' conflicts with built-in attribute/method".format(k))
|
||||||
|
|
||||||
# counter column primary keys are not allowed
|
# counter column primary keys are not allowed
|
||||||
if (v.primary_key or v.partition_key) and isinstance(v, (columns.Counter, columns.BaseContainerColumn)):
|
if (v.primary_key or v.partition_key) and isinstance(v, (columns.Counter, columns.BaseContainerColumn)):
|
||||||
raise ModelDefinitionException('counter columns and container columns cannot be used as primary keys')
|
raise ModelDefinitionException('counter columns and container columns cannot be used as primary keys')
|
||||||
@@ -661,7 +664,7 @@ class ModelMetaClass(type):
|
|||||||
if not has_partition_keys and v.primary_key:
|
if not has_partition_keys and v.primary_key:
|
||||||
v.partition_key = True
|
v.partition_key = True
|
||||||
has_partition_keys = True
|
has_partition_keys = True
|
||||||
_transform_column(k,v)
|
_transform_column(k, v)
|
||||||
|
|
||||||
partition_keys = OrderedDict(k for k in primary_keys.items() if k[1].partition_key)
|
partition_keys = OrderedDict(k for k in primary_keys.items() if k[1].partition_key)
|
||||||
clustering_keys = OrderedDict(k for k in primary_keys.items() if not k[1].partition_key)
|
clustering_keys = OrderedDict(k for k in primary_keys.items() if not k[1].partition_key)
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
from cqlengine.models import Model
|
from cqlengine.models import Model, ModelDefinitionException
|
||||||
from cqlengine import columns
|
from cqlengine import columns
|
||||||
|
|
||||||
|
|
||||||
@@ -31,3 +31,21 @@ class TestModel(TestCase):
|
|||||||
|
|
||||||
self.assertEqual(m0, m0)
|
self.assertEqual(m0, m0)
|
||||||
self.assertNotEqual(m0, m1)
|
self.assertNotEqual(m0, m1)
|
||||||
|
|
||||||
|
|
||||||
|
class BuiltInAttributeConflictTest(TestCase):
|
||||||
|
"""tests Model definitions that conflict with built-in attributes/methods"""
|
||||||
|
|
||||||
|
def test_model_with_attribute_name_conflict(self):
|
||||||
|
"""should raise exception when model defines column that conflicts with built-in attribute"""
|
||||||
|
with self.assertRaises(ModelDefinitionException):
|
||||||
|
class IllegalTimestampColumnModel(Model):
|
||||||
|
my_primary_key = columns.Integer(primary_key=True)
|
||||||
|
timestamp = columns.BigInt()
|
||||||
|
|
||||||
|
def test_model_with_method_name_conflict(self):
|
||||||
|
"""should raise exception when model defines column that conflicts with built-in method"""
|
||||||
|
with self.assertRaises(ModelDefinitionException):
|
||||||
|
class IllegalFilterColumnModel(Model):
|
||||||
|
my_primary_key = columns.Integer(primary_key=True)
|
||||||
|
filter = columns.Text()
|
Reference in New Issue
Block a user