@@ -43,6 +43,24 @@ def clickhouse(request) -> ClickHouseContainer:
43
43
os .path .dirname (__file__ ), "../../resource/tpch/data/orders.parquet"
44
44
)
45
45
client .insert_df ("orders" , pd .read_parquet (data_path ))
46
+ client .command ("""
47
+ CREATE TABLE customer (
48
+ c_custkey Int32,
49
+ c_name String,
50
+ c_address String,
51
+ c_nationkey Int32,
52
+ c_phone String,
53
+ c_acctbal Decimal(15,2),
54
+ c_mktsegment String,
55
+ c_comment String
56
+ )
57
+ ENGINE = MergeTree
58
+ ORDER BY (c_custkey)
59
+ """ )
60
+ data_path = os .path .join (
61
+ os .path .dirname (__file__ ), "../../resource/tpch/data/customer.parquet"
62
+ )
63
+ client .insert_df ("customer" , pd .read_parquet (data_path ))
46
64
request .addfinalizer (ch .stop )
47
65
return ch
48
66
@@ -87,9 +105,48 @@ class TestClickHouse:
87
105
"expression" : "toDateTime64('2024-01-01T23:59:59', 9, 'UTC')" ,
88
106
"type" : "timestamp" ,
89
107
},
108
+ {
109
+ "name" : "customer" ,
110
+ "type" : "Customer" ,
111
+ "relationship" : "OrdersCustomer" ,
112
+ },
113
+ {
114
+ "name" : "customer_name" ,
115
+ "type" : "varchar" ,
116
+ "isCalculated" : True ,
117
+ "expression" : "customer.name" ,
118
+ },
90
119
],
91
120
"primaryKey" : "orderkey" ,
92
- }
121
+ },
122
+ {
123
+ "name" : "Customer" ,
124
+ "refSql" : "select * from test.customer" ,
125
+ "columns" : [
126
+ {"name" : "custkey" , "expression" : "c_custkey" , "type" : "integer" },
127
+ {"name" : "name" , "expression" : "c_name" , "type" : "varchar" },
128
+ {
129
+ "name" : "orders" ,
130
+ "type" : "Orders" ,
131
+ "relationship" : "OrdersCustomer" ,
132
+ },
133
+ {
134
+ "name" : "totalprice" ,
135
+ "type" : "float" ,
136
+ "isCalculated" : True ,
137
+ "expression" : "sum(orders.totalprice)" ,
138
+ },
139
+ ],
140
+ "primaryKey" : "custkey" ,
141
+ },
142
+ ],
143
+ "relationships" : [
144
+ {
145
+ "name" : "OrdersCustomer" ,
146
+ "models" : ["Orders" , "Customer" ],
147
+ "joinType" : "MANY_TO_ONE" ,
148
+ "condition" : "Orders.custkey = Customer.custkey" ,
149
+ },
93
150
],
94
151
}
95
152
@@ -122,7 +179,7 @@ def test_query(self, clickhouse: ClickHouseContainer):
122
179
)
123
180
assert response .status_code == 200
124
181
result = response .json ()
125
- assert len (result ["columns" ]) == len ( self . manifest [ "models" ][ 0 ][ "columns" ])
182
+ assert len (result ["columns" ]) == 9
126
183
assert len (result ["data" ]) == 1
127
184
assert result ["data" ][0 ] == [
128
185
1 ,
@@ -133,6 +190,7 @@ def test_query(self, clickhouse: ClickHouseContainer):
133
190
"1_370" ,
134
191
1704153599000 ,
135
192
1704153599000 ,
193
+ "Customer#000000370" ,
136
194
]
137
195
assert result ["dtypes" ] == {
138
196
"orderkey" : "int32" ,
@@ -143,6 +201,7 @@ def test_query(self, clickhouse: ClickHouseContainer):
143
201
"order_cust_key" : "object" ,
144
202
"timestamp" : "datetime64[ns]" ,
145
203
"timestamptz" : "datetime64[ns, UTC]" ,
204
+ "customer_name" : "object" ,
146
205
}
147
206
148
207
def test_query_with_connection_url (self , clickhouse : ClickHouseContainer ):
@@ -157,7 +216,7 @@ def test_query_with_connection_url(self, clickhouse: ClickHouseContainer):
157
216
)
158
217
assert response .status_code == 200
159
218
result = response .json ()
160
- assert len (result ["columns" ]) == len ( self . manifest [ "models" ][ 0 ][ "columns" ])
219
+ assert len (result ["columns" ]) == 9
161
220
assert len (result ["data" ]) == 1
162
221
assert result ["data" ][0 ][0 ] == 1
163
222
assert result ["dtypes" ] is not None
@@ -180,7 +239,7 @@ def test_query_with_column_dtypes(self, clickhouse: ClickHouseContainer):
180
239
)
181
240
assert response .status_code == 200
182
241
result = response .json ()
183
- assert len (result ["columns" ]) == len ( self . manifest [ "models" ][ 0 ][ "columns" ])
242
+ assert len (result ["columns" ]) == 9
184
243
assert len (result ["data" ]) == 1
185
244
assert result ["data" ][0 ] == [
186
245
1 ,
@@ -191,6 +250,7 @@ def test_query_with_column_dtypes(self, clickhouse: ClickHouseContainer):
191
250
"1_370" ,
192
251
"2024-01-01 23:59:59.000000" ,
193
252
"2024-01-01 23:59:59.000000 UTC" ,
253
+ "Customer#000000370" ,
194
254
]
195
255
assert result ["dtypes" ] == {
196
256
"orderkey" : "int32" ,
@@ -201,6 +261,7 @@ def test_query_with_column_dtypes(self, clickhouse: ClickHouseContainer):
201
261
"order_cust_key" : "object" ,
202
262
"timestamp" : "object" ,
203
263
"timestamptz" : "object" ,
264
+ "customer_name" : "object" ,
204
265
}
205
266
206
267
def test_query_with_limit (self , clickhouse : ClickHouseContainer ):
@@ -231,6 +292,63 @@ def test_query_with_limit(self, clickhouse: ClickHouseContainer):
231
292
result = response .json ()
232
293
assert len (result ["data" ]) == 1
233
294
295
+ def test_query_join (self , clickhouse : ClickHouseContainer ):
296
+ connection_info = self .to_connection_info (clickhouse )
297
+ response = client .post (
298
+ url = f"{ self .base_url } /query" ,
299
+ json = {
300
+ "connectionInfo" : connection_info ,
301
+ "manifestStr" : self .manifest_str ,
302
+ "sql" : 'SELECT name as customer_name FROM "Orders" join "Customer" on "Orders".custkey = "Customer".custkey WHERE custkey = 370 LIMIT 1' ,
303
+ },
304
+ )
305
+ assert response .status_code == 200
306
+ result = response .json ()
307
+ assert len (result ["columns" ]) == 1
308
+ assert len (result ["data" ]) == 1
309
+ assert result ["data" ][0 ] == ["Customer#000000370" ]
310
+ assert result ["dtypes" ] == {
311
+ "customer_name" : "object" ,
312
+ }
313
+
314
+ def test_query_to_one_relationship (self , clickhouse : ClickHouseContainer ):
315
+ connection_info = self .to_connection_info (clickhouse )
316
+ response = client .post (
317
+ url = f"{ self .base_url } /query" ,
318
+ json = {
319
+ "connectionInfo" : connection_info ,
320
+ "manifestStr" : self .manifest_str ,
321
+ "sql" : 'SELECT customer_name FROM "Orders" where custkey = 370 LIMIT 1' ,
322
+ },
323
+ )
324
+ assert response .status_code == 200
325
+ result = response .json ()
326
+ assert len (result ["columns" ]) == 1
327
+ assert len (result ["data" ]) == 1
328
+ assert result ["data" ][0 ] == ["Customer#000000370" ]
329
+ assert result ["dtypes" ] == {
330
+ "customer_name" : "object" ,
331
+ }
332
+
333
+ def test_query_to_many_relationship (self , clickhouse : ClickHouseContainer ):
334
+ connection_info = self .to_connection_info (clickhouse )
335
+ response = client .post (
336
+ url = f"{ self .base_url } /query" ,
337
+ json = {
338
+ "connectionInfo" : connection_info ,
339
+ "manifestStr" : self .manifest_str ,
340
+ "sql" : 'SELECT totalprice FROM "Customer" where custkey = 370 LIMIT 1' ,
341
+ },
342
+ )
343
+ assert response .status_code == 200
344
+ result = response .json ()
345
+ assert len (result ["columns" ]) == 1
346
+ assert len (result ["data" ]) == 1
347
+ assert result ["data" ][0 ] == [2860895.79 ]
348
+ assert result ["dtypes" ] == {
349
+ "totalprice" : "object" ,
350
+ }
351
+
234
352
def test_query_without_manifest (self , clickhouse : ClickHouseContainer ):
235
353
connection_info = self .to_connection_info (clickhouse )
236
354
response = client .post (
0 commit comments