diff --git a/clickhouse_sqlalchemy/drivers/base.py b/clickhouse_sqlalchemy/drivers/base.py index b9ee6af6..1771b1cf 100644 --- a/clickhouse_sqlalchemy/drivers/base.py +++ b/clickhouse_sqlalchemy/drivers/base.py @@ -42,7 +42,8 @@ 'Enum8': types.Enum8, 'Enum16': types.Enum16, '_array': types.Array, - '_nullable': types.Nullable + '_nullable': types.Nullable, + '_lowcardinality': types.LowCardinality, } @@ -427,6 +428,10 @@ def visit_nullable(self, type_, **kw): nested_type = type_api.to_instance(type_.nested_type) return 'Nullable(%s)' % self.process(nested_type, **kw) + def visit_lowcardinality(self, type_, **kw): + nested_type = type_api.to_instance(type_.nested_type) + return "LowCardinality(%s)" % self.process(nested_type, **kw) + def visit_int8(self, type_, **kw): return 'Int8' @@ -582,6 +587,11 @@ def _get_column_type(self, name, spec): coltype = self.ischema_names['_nullable'] return coltype(self._get_column_type(name, inner)) + elif spec.startswith('LowCardinality'): + inner = spec[15:-1] + coltype = self.ischema_names['_lowcardinality'] + return coltype(self._get_column_type(name, inner)) + elif spec.startswith('Enum'): pos = spec.find('(') type = spec[:pos] diff --git a/clickhouse_sqlalchemy/types.py b/clickhouse_sqlalchemy/types.py index f536aea6..054a0ca8 100644 --- a/clickhouse_sqlalchemy/types.py +++ b/clickhouse_sqlalchemy/types.py @@ -51,6 +51,14 @@ class UUID(String): __visit_name__ = 'uuid' +class LowCardinality(types.TypeEngine): + __visit_name__ = 'lowcardinality' + + def __init__(self, nested_type): + self.nested_type = nested_type + super(LowCardinality, self).__init__() + + class Int8(Int): __visit_name__ = 'int8' diff --git a/tests/test_reflection.py b/tests/test_reflection.py index 87fccdb0..327bc2ac 100644 --- a/tests/test_reflection.py +++ b/tests/test_reflection.py @@ -49,6 +49,12 @@ def test_nullable(self): self.assertIsInstance(coltype, types.Nullable) self.assertEqual(coltype.nested_type, types.Int32) + def test_lowcardinality(self): + coltype = self._type_round_trip(types.LowCardinality(types.String))[0] + + self.assertIsInstance(coltype, types.LowCardinality) + self.assertEqual(coltype.nested_type, types.String) + def test_enum8(self): enum_options = {'three': 3, "quoted' ": 9, 'comma, ': 14} coltype = self._type_round_trip(