Add Tuple column type
PYTHON-306
This commit is contained in:
@@ -796,6 +796,65 @@ class UDTValueManager(BaseValueManager):
|
||||
self.previous_value = copy(self.value)
|
||||
|
||||
|
||||
class Tuple(Column):
|
||||
"""
|
||||
Stores a fixed-length set of positional values
|
||||
|
||||
http://docs.datastax.com/en/cql/3.1/cql/cql_reference/tupleType.html
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
:param args: column types representing tuple composition
|
||||
"""
|
||||
|
||||
self.db_type = 'tuple<{0}>'.format(', '.join(typ.db_type for typ in args))
|
||||
|
||||
if not args:
|
||||
raise ValueError("Tuple must specify at least one inner type")
|
||||
|
||||
sub_types = []
|
||||
for arg in args:
|
||||
inheritance_comparator = issubclass if isinstance(arg, type) else isinstance
|
||||
if not inheritance_comparator(arg, Column):
|
||||
raise ValidationError("%s is not a column class" % (arg,))
|
||||
if arg.db_type is None:
|
||||
raise ValidationError("%s is an abstract type" % (arg,))
|
||||
|
||||
sub_types.append(arg() if isinstance(arg, type) else arg)
|
||||
self.sub_types = sub_types
|
||||
|
||||
super(Tuple, self).__init__(**kwargs)
|
||||
|
||||
def validate(self, value):
|
||||
val = super(Tuple, self).validate(value)
|
||||
if val is None:
|
||||
return
|
||||
if len(val) > self.sub_types:
|
||||
raise ValidationError("Value %r has more fields than tuple definition (%s)" %
|
||||
(val, ', '.join(t for t in self.sub_types)))
|
||||
return tuple(t.validate(v) for t, v in zip(self.sub_types, val))
|
||||
|
||||
def to_python(self, value):
|
||||
if value is None:
|
||||
return tuple()
|
||||
return tuple(t.to_python(v) for t, v in zip(self.sub_types, value))
|
||||
|
||||
def to_database(self, value):
|
||||
if value is None:
|
||||
return
|
||||
return tuple(t.to_database(v) for t, v in zip(self.sub_types, value))
|
||||
|
||||
@property
|
||||
def sub_columns(self):
|
||||
return self.sub_types
|
||||
|
||||
# TODO:
|
||||
# sub_columns --> sub_types
|
||||
# test UDTs in tuples, vice versa
|
||||
# refactor init validation to common base
|
||||
# cqlsh None in tuple should display as null
|
||||
|
||||
|
||||
class UserDefinedType(Column):
|
||||
"""
|
||||
User Defined Type column
|
||||
|
||||
@@ -56,9 +56,8 @@ def default():
|
||||
|
||||
cluster = Cluster()
|
||||
session = cluster.connect()
|
||||
session.row_factory = dict_factory
|
||||
|
||||
_register_known_types(cluster)
|
||||
_setup_session(session)
|
||||
|
||||
log.debug("cqlengine connection initialized with default session to localhost")
|
||||
|
||||
@@ -85,7 +84,7 @@ def set_session(s):
|
||||
if not models.DEFAULT_KEYSPACE and session.keyspace:
|
||||
models.DEFAULT_KEYSPACE = session.keyspace
|
||||
|
||||
_register_known_types(cluster)
|
||||
_setup_session(session)
|
||||
|
||||
log.debug("cqlengine connection initialized with %s", s)
|
||||
|
||||
@@ -138,9 +137,15 @@ def setup(
|
||||
raise
|
||||
if consistency is not None:
|
||||
session.default_consistency_level = consistency
|
||||
session.row_factory = dict_factory
|
||||
|
||||
_register_known_types(cluster)
|
||||
_setup_session(session)
|
||||
|
||||
|
||||
def _setup_session(session):
|
||||
session.row_factory = dict_factory
|
||||
enc = session.encoder
|
||||
enc.mapping[tuple] = enc.cql_encode_tuple
|
||||
_register_known_types(session.cluster)
|
||||
|
||||
|
||||
def execute(query, params=None, consistency_level=None, timeout=NOT_SET):
|
||||
|
||||
@@ -84,7 +84,7 @@ class Encoder(object):
|
||||
OrderedMap: self.cql_encode_map_collection,
|
||||
OrderedMapSerializedKey: self.cql_encode_map_collection,
|
||||
list: self.cql_encode_list_collection,
|
||||
tuple: self.cql_encode_list_collection,
|
||||
tuple: self.cql_encode_list_collection, # TODO: change to tuple in next major
|
||||
set: self.cql_encode_set_collection,
|
||||
sortedset: self.cql_encode_set_collection,
|
||||
frozenset: self.cql_encode_set_collection,
|
||||
|
||||
Reference in New Issue
Block a user