|
| 1 | +import json |
| 2 | +from sqlalchemy import Column, text, inspect, func |
| 3 | +from sqlalchemy.sql.ddl import CreateTable |
| 4 | + |
| 5 | +from clickhouse_sqlalchemy import types, engines, Table |
| 6 | +from tests.testcase import BaseTestCase, CompilationTestCase |
| 7 | +from tests.util import class_name_func |
| 8 | +from parameterized import parameterized_class |
| 9 | +from tests.session import native_session |
| 10 | + |
| 11 | + |
| 12 | +class JSONCompilationTestCase(CompilationTestCase): |
| 13 | + def test_create_table(self): |
| 14 | + table = Table( |
| 15 | + 'test', CompilationTestCase.metadata(), |
| 16 | + Column('x', types.JSON), |
| 17 | + engines.Memory() |
| 18 | + ) |
| 19 | + |
| 20 | + self.assertEqual( |
| 21 | + self.compile(CreateTable(table)), |
| 22 | + 'CREATE TABLE test (x JSON) ENGINE = Memory' |
| 23 | + ) |
| 24 | + |
| 25 | + |
| 26 | +@parameterized_class( |
| 27 | + [{'session': native_session}], |
| 28 | + class_name_func=class_name_func |
| 29 | +) |
| 30 | +class JSONTestCase(BaseTestCase): |
| 31 | + required_server_version = (22, 3, 2) |
| 32 | + |
| 33 | + table = Table( |
| 34 | + 'test', BaseTestCase.metadata(), |
| 35 | + Column('x', types.JSON), |
| 36 | + engines.Memory() |
| 37 | + ) |
| 38 | + |
| 39 | + def test_select_insert(self): |
| 40 | + data = {'k1': 1, 'k2': '2', 'k3': True} |
| 41 | + |
| 42 | + self.table.drop(bind=self.session.bind, if_exists=True) |
| 43 | + try: |
| 44 | + # http session is unsupport |
| 45 | + self.session.execute( |
| 46 | + text('SET allow_experimental_object_type = 1;') |
| 47 | + ) |
| 48 | + self.session.execute(text(self.compile(CreateTable(self.table)))) |
| 49 | + self.session.execute(self.table.insert(), [{'x': data}]) |
| 50 | + coltype = inspect(self.session.bind).get_columns('test')[0]['type'] |
| 51 | + self.assertIsInstance(coltype, types.JSON) |
| 52 | + # https://clickhouse.com/docs/en/sql-reference/functions/json-functions#tojsonstring |
| 53 | + # The json type returns a tuple of values by default, |
| 54 | + # which needs to be converted to json using the |
| 55 | + # toJSONString function. |
| 56 | + res = self.session.query( |
| 57 | + func.toJSONString(self.table.c.x) |
| 58 | + ).scalar() |
| 59 | + self.assertEqual(json.loads(res), data) |
| 60 | + finally: |
| 61 | + self.table.drop(bind=self.session.bind, if_exists=True) |
0 commit comments