Skip to content

Commit bd1c670

Browse files
committed
feat: Allow setting of columnar and use_numpy for given_query
1 parent 0535cb9 commit bd1c670

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

clickhouse_backend/driver/connection.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import re
2+
import typing as T
3+
from contextlib import contextmanager
24

35
from clickhouse_driver import connection
46
from clickhouse_driver.dbapi import connection as dbapi_connection
57
from clickhouse_driver.dbapi import cursor, errors
8+
from clickhouse_driver.result import IterQueryResult, ProgressQueryResult, QueryResult
69
from django.conf import settings
710

811
from .escape import escape_params
@@ -70,6 +73,11 @@ def send_query(self, query, query_id=None, params=None):
7073

7174

7275
class Cursor(cursor.Cursor):
76+
77+
# Whether to return data in columnar format. For backwards-compatibility,
78+
# let's default to None.
79+
columnar = None
80+
7381
def close(self):
7482
"""Push client back to connection pool"""
7583
if self.closed:
@@ -81,12 +89,64 @@ def close(self):
8189
def closed(self):
8290
return self._state == self._states.CURSOR_CLOSED
8391

92+
@property
93+
def use_numpy(self):
94+
return self._client.client_settings["use_numpy"]
95+
96+
@use_numpy.setter
97+
def use_numpy(self, value):
98+
self._client.client_settings["use_numpy"] = value
99+
if value:
100+
try:
101+
from clickhouse_driver.numpy.result import (
102+
NumpyIterQueryResult,
103+
NumpyProgressQueryResult,
104+
NumpyQueryResult,
105+
)
106+
107+
self._client.query_result_cls = NumpyQueryResult
108+
self._client.iter_query_result_cls = NumpyIterQueryResult
109+
self._client.progress_query_result_cls = NumpyProgressQueryResult
110+
except ImportError as e:
111+
raise RuntimeError("Extras for NumPy must be installed") from e
112+
else:
113+
self._client.query_result_cls = QueryResult
114+
self._client.iter_query_result_cls = IterQueryResult
115+
self._client.progress_query_result_cls = ProgressQueryResult
116+
117+
@contextmanager
118+
def set_query_args(
119+
self, columnar: T.Optional[bool] = None, use_numpy: T.Optional[bool] = None
120+
):
121+
original_use_numpy = self.use_numpy
122+
if use_numpy is not None:
123+
self.use_numpy = use_numpy
124+
125+
original_columnar = self.columnar
126+
if columnar is not None:
127+
self.columnar = columnar
128+
129+
yield self
130+
131+
self.use_numpy = original_use_numpy
132+
self.columnar = original_columnar
133+
84134
def __del__(self):
85135
# If someone forgets calling close method,
86136
# then release connection when gc happens.
87137
if not self.closed:
88138
self.close()
89139

140+
def _prepare(self):
141+
"""Override clickhouse_driver.Cursor._prepare() to add columnar kwargs.
142+
143+
See https://github.com/jayvynl/django-clickhouse-backend/issues/119
144+
"""
145+
execute, execute_kwargs = super()._prepare()
146+
if self.columnar is not None:
147+
execute_kwargs["columnar"] = self.columnar
148+
return execute, execute_kwargs
149+
90150
def execute(self, operation, parameters=None):
91151
"""fix https://github.com/jayvynl/django-clickhouse-backend/issues/9"""
92152
if getattr(

0 commit comments

Comments
 (0)