From ddf953148b1c39f95a9c79e4a21b4c3060871462 Mon Sep 17 00:00:00 2001 From: Kanthi Date: Thu, 5 Oct 2023 14:15:59 -0400 Subject: [PATCH] Add logic to escape Map data type to support insert statements. (#266) * Add logic to escape Map data type to support insert statements. --- clickhouse_sqlalchemy/drivers/http/escaper.py | 7 +++++++ tests/drivers/http/test_escaping.py | 2 +- tests/sql/test_insert.py | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/clickhouse_sqlalchemy/drivers/http/escaper.py b/clickhouse_sqlalchemy/drivers/http/escaper.py index 10ebf991..ab259f10 100644 --- a/clickhouse_sqlalchemy/drivers/http/escaper.py +++ b/clickhouse_sqlalchemy/drivers/http/escaper.py @@ -66,6 +66,13 @@ def escape_item(self, item): return "[" + ", ".join( [str(self.escape_item(x)) for x in item] ) + "]" + elif isinstance(item, dict): + return "{" + ", ".join( + ["{}: {}".format( + self.escape_item(k), + self.escape_item(v) + ) for k, v in item.items()] + ) + "}" elif isinstance(item, enum.Enum): return self.escape_string(item.name) else: diff --git a/tests/drivers/http/test_escaping.py b/tests/drivers/http/test_escaping.py index 0f549d2c..a456ecc9 100644 --- a/tests/drivers/http/test_escaping.py +++ b/tests/drivers/http/test_escaping.py @@ -28,7 +28,7 @@ def test_escaper(self): self.assertEqual(e.escape([Decimal('10')]), '[10.0]') self.assertEqual(e.escape([10.0]), '[10.0]') self.assertEqual(e.escape([date(2017, 1, 2)]), "['2017-01-02']") - + self.assertEqual(e.escape(dict(x=10, y=20)), {'x': 10, 'y': 20}) with self.assertRaises(Exception) as ex: e.escape([object()]) diff --git a/tests/sql/test_insert.py b/tests/sql/test_insert.py index 70b44532..26d2fdc1 100644 --- a/tests/sql/test_insert.py +++ b/tests/sql/test_insert.py @@ -20,3 +20,22 @@ def test_insert(self): rv = self.session.execute(select(table.c.x)).scalar() self.assertEqual(rv, 'test') + + @require_server_version(21, 1, 3) + def test_insert_map(self): + table = Table( + 't', self.metadata(), + Column('x', types.Map(types.String, types.Int32), + primary_key=True), + engines.Memory() + ) + + with self.create_table(table): + dict_map = dict(key1=1, Key2=2) + x = [ + {'x': dict_map} + ] + self.session.execute(table.insert(), x) + + rv = self.session.execute(select(table.c.x)).scalar() + self.assertEqual(rv, dict_map)