Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix query_context.updated_copy method, add first examples #66

Merged
merged 1 commit into from
Nov 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/on_push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
run: |
pylint clickhouse_connect
pylint tests
pylint examples

tests:
runs-on: ubuntu-latest
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
## ClickHouse Connect ChangeLog


### Release 0.3.6 2022-11-02

#### Bug Fix
* Update QueryContext.updated_copy method to preserve settings, parameters, etc. https://github.com/ClickHouse/clickhouse-connect/issues/65



### Release 0.3.5 2022-10-28

#### Improvement
Expand Down
2 changes: 1 addition & 1 deletion clickhouse_connect/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.3.5
0.3.6
9 changes: 8 additions & 1 deletion clickhouse_connect/driver/common.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import array
import sys

from typing import Tuple, Sequence, MutableSequence
from typing import Tuple, Sequence, MutableSequence, Dict, Optional

# pylint: disable=invalid-name
must_swap = sys.byteorder == 'big'
Expand Down Expand Up @@ -171,3 +171,10 @@ def unescape_identifier(x: str) -> str:
if x.startswith('`') and x.endswith('`'):
return x[1:-1]
return x


def dict_copy(source: Dict = None, update: Optional[Dict] = None) -> Dict:
copy = source.copy() if source else {}
if update:
copy.update(update)
return copy
9 changes: 5 additions & 4 deletions clickhouse_connect/driver/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from typing import NamedTuple, Any, Tuple, Dict, Sequence, Optional, Union
from datetime import date, datetime, tzinfo

from clickhouse_connect.driver.common import dict_copy
from clickhouse_connect.json_impl import any_to_json
from clickhouse_connect.common import common_settings
from clickhouse_connect.datatypes.base import ClickHouseType
Expand Down Expand Up @@ -114,10 +115,10 @@ def updated_copy(self,
Creates Query context copy with parameters overridden/updated as appropriate
"""
return QueryContext(query or self.query,
self.parameters.update(parameters or {}),
self.settings.update(settings or {}),
self.query_formats.update(query_formats or {}),
self.column_formats.update(column_formats or {}),
dict_copy(self.parameters, parameters),
dict_copy(self.settings, settings),
dict_copy(self.query_formats, query_formats),
dict_copy(self.column_formats, column_formats),
encoding if encoding else self.encoding,
server_tz if server_tz else self.server_tz,
use_none if use_none is not None else self.use_none)
Expand Down
6 changes: 3 additions & 3 deletions clickhouse_connect/driverc/creaders.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions examples/pandas_examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import pandas as pd
import clickhouse_connect


create_table_sql = """
CREATE TABLE pandas_example
(
`timeseries` DateTime('UTC'),
`int_value` Int32,
`str_value` String,
`float_value` Float64
)
ENGINE = MergeTree
ORDER BY timeseries
"""


def write_pandas_df():
client = clickhouse_connect.get_client(host='localhost', port='8123', user_name='default', password = '')
client.command('DROP TABLE IF EXISTS pandas_example')
client.command(create_table_sql)
df = pd.DataFrame({'timeseries': ['04/03/2022 10:00:11', '05/03/2022 11:15:44', '06/03/2022 17:14:00'],
'int_value': [16, 19, 11],
'str_value': ['String One', 'String Two', 'A Third String'],
'float_value': [2344.288, -73002.4444, 3.14159]})
df['timeseries'] = pd.to_datetime(df['timeseries'])
client.insert_df('pandas_example', df)
result_df = client.query_df('SELECT * FROM pandas_example')
print()
print(result_df.dtypes)
print()
print(result_df)


if __name__ == '__main__':
write_pandas_df()
57 changes: 57 additions & 0 deletions examples/params_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from datetime import datetime, timedelta

from clickhouse_connect.driver.query import finalize_query

select_template = """
SELECT
formatDateTime(started_at, '%%m/%%d/%%Y', %(time_zone)s) AS date,
formatDateTime(started_at, '%%I:%%M:%%S %%p', %(time_zone)s) AS time,
format('{}path/link?name={}&dev_type={}', %(web_url)s, label, device_type) AS url,
device_name,
description
FROM sessions
"""


def build_device_query(time_zone: str,
web_url: str,
client: str,
company_id: str = '',
device_id: str = '',
updated: bool = False,
start_time: datetime = None,
end_time: datetime = None):
params = {'time_zone': time_zone,
'web_url': web_url,
'client': client
}
where_template = ' WHERE client = %(client)s'
if company_id:
where_template += ' AND company_id = %(company_id)s'
params['company_id'] = company_id
if device_id:
where_template += ' AND dev_type = %(device_id)s'
params['device_id'] = device_id
if updated:
where_template += ' AND updated = true'
if start_time and end_time:
where_template += ' AND started_at BETWEEN %(start_time)s AND %(end_time)s'
params['start_time'] = start_time
params['end_time'] = end_time
full_query = select_template + where_template + ' ORDER BY started_at ASC'
return finalize_query(full_query, params)


if __name__ == '__main__':
start = datetime.now()
end = start + timedelta(hours=1, minutes=20)
print(build_device_query('UTC',
'https://example.com',

client='Client_0',
company_id='Company_1',
device_id='DEVICE_77',
start_time=start,
end_time=end
)
)
26 changes: 26 additions & 0 deletions tests/unit_tests/test_driver/test_query.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from clickhouse_connect.driver.query import QueryContext


def test_copy_context():
settings = {'max_bytes_for_external_group_by': 1024 * 1024 * 100,
'read_overflow_mode': 'throw'}
parameters = {'user_id': 'user_1'}
query_formats = {'IPv*': 'string'}
context = QueryContext('SELECT source_ip FROM table WHERE user_id = %(user_id)s',
settings=settings,
parameters=parameters,
query_formats=query_formats,
use_none=True)
assert context.use_none is True
assert context.final_query == "SELECT source_ip FROM table WHERE user_id = 'user_1'"
assert context.query_formats['IPv*'] == 'string'
assert context.settings['max_bytes_for_external_group_by'] == 104857600

context_copy = context.updated_copy(
settings={'max_bytes_for_external_group_by': 1024 * 1024 * 24, 'max_execution_time': 120},
parameters={'user_id': 'user_2'}
)
assert context_copy.settings['read_overflow_mode'] == 'throw'
assert context_copy.settings['max_execution_time'] == 120
assert context_copy.settings['max_bytes_for_external_group_by'] == 25165824
assert context_copy.final_query == "SELECT source_ip FROM table WHERE user_id = 'user_2'"