{"id":13695785,"url":"https://github.com/maximdanilchenko/aiochclient","last_synced_at":"2025-05-16T10:08:34.763Z","repository":{"id":32976561,"uuid":"147911533","full_name":"maximdanilchenko/aiochclient","owner":"maximdanilchenko","description":"Lightweight async http(s) ClickHouse client for python 3.6+ with types converting","archived":false,"fork":false,"pushed_at":"2024-10-08T12:53:36.000Z","size":487,"stargazers_count":255,"open_issues_count":23,"forks_count":49,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-05-12T02:18:18.714Z","etag":null,"topics":["aiohttp","async","asyncio","clickhouse","client","database","driver","httpx","python"],"latest_commit_sha":null,"homepage":"https://aiochclient.readthedocs.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/maximdanilchenko.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-08T07:23:09.000Z","updated_at":"2025-04-22T16:43:39.000Z","dependencies_parsed_at":"2023-02-15T16:16:23.541Z","dependency_job_id":"8602017c-c8cf-45fe-aad5-effdaa0c1a67","html_url":"https://github.com/maximdanilchenko/aiochclient","commit_stats":{"total_commits":229,"total_committers":22,"mean_commits":"10.409090909090908","dds":0.5807860262008734,"last_synced_commit":"5054c8dc9c7cca6cecb515711bf42a8244a70ed5"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maximdanilchenko%2Faiochclient","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maximdanilchenko%2Faiochclient/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maximdanilchenko%2Faiochclient/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maximdanilchenko%2Faiochclient/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maximdanilchenko","download_url":"https://codeload.github.com/maximdanilchenko/aiochclient/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254509477,"owners_count":22082892,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aiohttp","async","asyncio","clickhouse","client","database","driver","httpx","python"],"created_at":"2024-08-02T18:00:33.414Z","updated_at":"2025-05-16T10:08:29.752Z","avatar_url":"https://github.com/maximdanilchenko.png","language":"Python","funding_links":[],"categories":["Python","Language bindings"],"sub_categories":["Python"],"readme":"# aiochclient\r\n\r\n[![PyPI version](https://badge.fury.io/py/aiochclient.svg)](https://badge.fury.io/py/aiochclient)\r\n[![Tests](https://github.com/maximdanilchenko/aiochclient/actions/workflows/tests.yml/badge.svg)](https://github.com/maximdanilchenko/aiochclient/actions/workflows/tests.yml)\r\n[![Documentation Status](https://readthedocs.org/projects/aiochclient/badge/?version=latest)](https://aiochclient.readthedocs.io/en/latest/?badge=latest)\r\n[![codecov](https://codecov.io/gh/maximdanilchenko/aiochclient/branch/master/graph/badge.svg)](https://codecov.io/gh/maximdanilchenko/aiochclient)\r\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\r\n\r\n\r\nAn async http(s) ClickHouse client for python 3.6+ supporting type\r\nconversion in both directions, streaming, lazy decoding on select queries, and a\r\nfully typed interface.\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Quick Start](#quick-start)\r\n- [Documentation](#documentation)\r\n- [Type Conversion](#type-conversion)\r\n- [Connection Pool Settings](#connection-pool-settings)\r\n- [Notes on Speed](#notes-on-speed)\r\n\r\n## Installation\r\n\r\nYou can use it with either\r\n[aiohttp](https://github.com/aio-libs/aiohttp) or\r\n[httpx](https://github.com/encode/httpx) http connectors.\r\n\r\nTo use with `aiohttp` install it with command:\r\n\r\n```\r\n\u003e pip install aiochclient[aiohttp]\r\n```\r\n\r\nOr `aiochclient[aiohttp-speedups]` to install with extra speedups.\r\n\r\nTo use with `httpx` install it with command:\r\n\r\n```\r\n\u003e pip install aiochclient[httpx]\r\n```\r\n\r\nOr `aiochclient[httpx-speedups]` to install with extra speedups.\r\n\r\nInstalling with `[*-speedups]` adds the following:\r\n\r\n- [cChardet](https://pypi.python.org/pypi/cchardet) for `aiohttp` speedup\r\n- [aiodns](https://pypi.python.org/pypi/aiodns) for `aiohttp` speedup\r\n- [ciso8601](https://github.com/closeio/ciso8601) for ultra-fast datetime\r\n  parsing while decoding data from ClickHouse for `aiohttp` and `httpx`.\r\n\r\nAdditionally the installation process attempts to use Cython for a speed boost\r\n(roughly 30% faster).\r\n\r\n## Quick Start\r\n\r\n### Connecting to ClickHouse\r\n\r\n`aiochclient` needs `aiohttp.ClientSession` or `httpx.AsyncClient` to connect to ClickHouse:\r\n\r\n```python\r\nfrom aiochclient import ChClient\r\nfrom aiohttp import ClientSession\r\n\r\n\r\nasync def main():\r\n    async with ClientSession() as s:\r\n        client = ChClient(s)\r\n        assert await client.is_alive()  # returns True if connection is Ok\r\n\r\n```\r\n\r\n### Querying the database\r\n\r\n```python\r\nawait client.execute(\r\n    \"CREATE TABLE t (a UInt8, b Tuple(Date, Nullable(Float32))) ENGINE = Memory\"\r\n)\r\n```\r\n\r\nFor INSERT queries you can pass values as `*args`. Values should be\r\niterables:\r\n\r\n```python\r\nawait client.execute(\r\n    \"INSERT INTO t VALUES\",\r\n    (1, (dt.date(2018, 9, 7), None)),\r\n    (2, (dt.date(2018, 9, 8), 3.14)),\r\n)\r\n```\r\n\r\nFor fetching all rows at once use the\r\n[`fetch`](https://aiochclient.readthedocs.io/en/latest/api.html#aiochclient.ChClient.fetch)\r\nmethod:\r\n\r\n```python\r\nall_rows = await client.fetch(\"SELECT * FROM t\")\r\n```\r\n\r\nFor fetching first row from result use the\r\n[`fetchrow`](https://aiochclient.readthedocs.io/en/latest/api.html#aiochclient.ChClient.fetchrow)\r\nmethod:\r\n\r\n```python\r\nrow = await client.fetchrow(\"SELECT * FROM t WHERE a=1\")\r\n\r\nassert row[0] == 1\r\nassert row[\"b\"] == (dt.date(2018, 9, 7), None)\r\n```\r\n\r\nYou can also use\r\n[`fetchval`](https://aiochclient.readthedocs.io/en/latest/api.html#aiochclient.ChClient.fetchval)\r\nmethod, which returns first value of the first row from query result:\r\n\r\n```python\r\nval = await client.fetchval(\"SELECT b FROM t WHERE a=2\")\r\n\r\nassert val == (dt.date(2018, 9, 8), 3.14)\r\n```\r\n\r\nWith async iteration on the query results stream you can fetch multiple\r\nrows without loading them all into memory at once:\r\n\r\n```python\r\nasync for row in client.iterate(\r\n        \"SELECT number, number*2 FROM system.numbers LIMIT 10000\"\r\n):\r\n    assert row[0] * 2 == row[1]\r\n```\r\n\r\nUse `fetch`/`fetchrow`/`fetchval`/`iterate` for SELECT queries and `execute` or\r\nany of last for INSERT and all another queries.\r\n\r\n### Working with query results\r\n\r\nAll fetch queries return rows as lightweight, memory efficient objects. _Before\r\nv`1.0.0` rows were only returned as tuples._ All rows have a full mapping interface, where you can\r\nget fields by names or indexes:\r\n\r\n```python\r\nrow = await client.fetchrow(\"SELECT a, b FROM t WHERE a=1\")\r\n\r\nassert row[\"a\"] == 1\r\nassert row[0] == 1\r\nassert row[:] == (1, (dt.date(2018, 9, 8), 3.14))\r\nassert list(row.keys()) == [\"a\", \"b\"]\r\nassert list(row.values()) == [1, (dt.date(2018, 9, 8), 3.14)]\r\n```\r\n\r\n## Documentation\r\n\r\nTo check out the [api docs](https://aiochclient.readthedocs.io/en/latest/api.html),\r\nvisit the [readthedocs site.](https://aiochclient.readthedocs.io/en/latest/).\r\n\r\n## Type Conversion\r\n\r\n`aiochclient` automatically converts types from ClickHouse to python types and\r\nvice-versa.\r\n\r\n\r\n| ClickHouse type      | Python type             |\r\n|:---------------------|:------------------------|\r\n| `Bool`               | `bool`                  |\r\n| `UInt8`              | `int`                   |\r\n| `UInt16`             | `int`                   |\r\n| `UInt32`             | `int`                   |\r\n| `UInt64`             | `int`                   |\r\n| `UInt128`            | `int`                   |\r\n| `UInt256`            | `int`                   |\r\n| `Int8`               | `int`                   |\r\n| `Int16`              | `int`                   |\r\n| `Int32`              | `int`                   |\r\n| `Int64`              | `int`                   |\r\n| `Int128`             | `int`                   |\r\n| `Int256`             | `int`                   |\r\n| `Float32`            | `float`                 |\r\n| `Float64`            | `float`                 |\r\n| `String`             | `str`                   |\r\n| `FixedString`        | `str`                   |\r\n| `Enum8`              | `str`                   |\r\n| `Enum16`             | `str`                   |\r\n| `Date`               | `datetime.date`         |\r\n| `DateTime`           | `datetime.datetime`     |\r\n| `DateTime64`         | `datetime.datetime`     |\r\n| `Decimal`            | `decimal.Decimal`       |\r\n| `Decimal32`          | `decimal.Decimal`       |\r\n| `Decimal64`          | `decimal.Decimal`       |\r\n| `Decimal128`         | `decimal.Decimal`       |\r\n| `IPv4`               | `ipaddress.IPv4Address` |\r\n| `IPv6`               | `ipaddress.IPv6Address` |\r\n| `UUID`               | `uuid.UUID`             |\r\n| `Nothing`            | `None`                  |\r\n| `Tuple(T1, T2, ...)` | `Tuple[T1, T2, ...]`    |\r\n| `Array(T)`           | `List[T]`               |\r\n| `Nullable(T)`        | `None` or `T`           |\r\n| `LowCardinality(T)`  | `T`                     |\r\n| `Map(T1, T2)`        | `Dict[T1, T2]`          |\r\n| `Nested(T1, T2, ...)` | `List[Tuple[T1, T2, ...], Tuple[T1, T2, ...]]` |\r\n\r\n\r\n## Connection Pool Settings\r\n\r\n`aiochclient` uses the\r\n[aiohttp.TCPConnector](https://docs.aiohttp.org/en/stable/client_advanced.html#limiting-connection-pool-size)\r\nto determine pool size. By default, the pool limit is 100 open connections.\r\n\r\n## Notes on Speed\r\n\r\nIt's highly recommended using `uvloop` and installing `aiochclient` with\r\nspeedups for the sake of speed. Some recent benchmarks on our\r\nmachines without parallelization:\r\n\r\n- 180k-220k rows/sec on SELECT\r\n- 50k-80k rows/sec on INSERT\r\n\r\n_Note: these benchmarks are system dependent_\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaximdanilchenko%2Faiochclient","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaximdanilchenko%2Faiochclient","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaximdanilchenko%2Faiochclient/lists"}