{"id":13695775,"url":"https://github.com/long2ice/asynch","last_synced_at":"2025-05-16T09:02:44.866Z","repository":{"id":37672837,"uuid":"290518295","full_name":"long2ice/asynch","owner":"long2ice","description":"An asyncio ClickHouse Python Driver with native (TCP) interface support.","archived":false,"fork":false,"pushed_at":"2025-05-06T13:55:51.000Z","size":589,"stargazers_count":196,"open_issues_count":23,"forks_count":46,"subscribers_count":7,"default_branch":"dev","last_synced_at":"2025-05-06T14:15:56.086Z","etag":null,"topics":["asyncio","clickhouse","driver","native","yandex"],"latest_commit_sha":null,"homepage":"https://github.com/long2ice/asynch","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/long2ice.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2020-08-26T14:25:00.000Z","updated_at":"2025-05-06T05:49:40.000Z","dependencies_parsed_at":"2024-06-05T23:17:26.908Z","dependency_job_id":"10e49f8a-bdb0-4e99-b281-7aa23222c674","html_url":"https://github.com/long2ice/asynch","commit_stats":{"total_commits":148,"total_committers":22,"mean_commits":"6.7272727272727275","dds":0.6216216216216216,"last_synced_commit":"57ab436fc0352bccc9b1dfa8ba81580fca98b1ed"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/long2ice%2Fasynch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/long2ice%2Fasynch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/long2ice%2Fasynch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/long2ice%2Fasynch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/long2ice","download_url":"https://codeload.github.com/long2ice/asynch/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254501548,"owners_count":22081526,"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":["asyncio","clickhouse","driver","native","yandex"],"created_at":"2024-08-02T18:00:33.352Z","updated_at":"2025-05-16T09:02:44.851Z","avatar_url":"https://github.com/long2ice.png","language":"Python","readme":"# asynch\n\n![pypi](https://img.shields.io/pypi/v/asynch.svg?style=flat)\n![license](https://img.shields.io/github/license/long2ice/asynch)\n![workflows](https://github.com/long2ice/asynch/workflows/pypi/badge.svg)\n![workflows](https://github.com/long2ice/asynch/workflows/ci/badge.svg)\n\n## Introduction\n\n`asynch` is an asynchronous ClickHouse Python driver with native TCP interface support, which reuses most of [clickhouse-driver](https://github.com/mymarilyn/clickhouse-driver) features and complies with [PEP249](https://www.python.org/dev/peps/pep-0249/).\n\n## Installation\n\n```shell\n\u003e pip install asynch\n```\n\nIf you want to install [`clickhouse-cityhash`](https://pypi.org/project/clickhouse-cityhash/) to enable transport compression\n\n```shell\n\u003e pip install asynch[compression]\n```\n\n## Release v0.3.0 announcement\n\nThe version 0.2.5 should have been the v0.3.0 due to compatibility-breaking changes.\nBefore upgrading to the v0.3.0, please pay attention to the incompatible changes like:\n\n- The `asynch/connection.py::connect` function is removed - you can use the `async with` a Connection instance.\n- The `asynch/connection.py::Connection.connected` property is renamed to `opened`.\n- The `asynch/pool.py::create_pool` function is removed - you can use the `async with` a Pool instance.\n- The deprecated methods from `Connection`, `Cursor` and `Pool` classes are removed.\n\nFor more details, please refer to the project [CHANGELOG.md](./CHANGELOG.md) file.\n\n## Usage\n\nBasically, a connection to a ClickHouse server can be established in two ways:\n\n1. with a DSN string, e.g., `clickhouse://[user:password]@host:port/database`;\n\n    ```python\n    from asynch import Connection\n\n    # connecting with a DSN string\n    async def connect_database():\n        async with Connection(\n            dsn = \"clickhouse://ch_user:P@55w0rD:@127.0.0.1:9000/chdb\",\n        ) as conn:\n            pass\n    ```\n\n2. with separately given connection/DSN parameters: `user` (optional), `password` (optional), `host`, `port`, `database`.\n\n    ```python\n    from asynch import Connection\n\n    # connecting with DSN parameters\n    async def connect_database():\n        async with Connection(\n            user = \"ch_user\",\n            password = \"P@55w0rD\",\n            host = \"127.0.0.1\",\n            port = 9000,\n            database = \"chdb\",\n        ) as conn:\n            pass\n    ```\n\nIf a DSN string is given, it takes priority over any specified connection parameter.\n\nCreate a database and a table by executing SQL statements via an instance of the `Cursor` class (here its child `DictCursor` class) acquired from an instance of the `Connection` class.\n\n```python\nasync def create_table(conn: Connection):\n    async with conn.cursor(cursor=DictCursor) as cursor:\n        await cursor.execute(\"CREATE DATABASE IF NOT EXISTS test\")\n        await cursor.execute(\"\"\"\n            CREATE TABLE if not exists test.asynch\n            (\n                `id`       Int32,\n                `decimal`  Decimal(10, 2),\n                `date`     Date,\n                `datetime` DateTime,\n                `float`    Float32,\n                `uuid`     UUID,\n                `string`   String,\n                `ipv4`     IPv4,\n                `ipv6`     IPv6\n            )\n            ENGINE = MergeTree\n            ORDER BY id\n            \"\"\"\n        )\n```\n\nFetching one row from an executed SQL statement:\n\n```python\nasync def fetchone(conn: Connection):\n    # by default, an instance of the `Cursor` class\n    async with conn.cursor() as cursor:\n        await cursor.execute(\"SELECT 1\")\n        ret = await cursor.fetchone()\n        assert ret == (1,)\n```\n\nFetching all the rows from an executed SQL statement:\n\n```python\nasync def fetchall():\n    async with conn.cursor() as cursor:\n        await cursor.execute(\"SELECT 1\")\n        ret = await cursor.fetchall()\n        assert ret == [(1,)]\n```\n\nUsing an instance of the `DictCursor` class to get results as a sequence of `dict`ionaries representing the rows of an executed SQL query:\n\n```python\nasync def dict_cursor():\n    async with conn.cursor(cursor=DictCursor) as cursor:\n        await cursor.execute(\"SELECT 1\")\n        ret = await cursor.fetchall()\n        assert ret == [{\"1\": 1}]\n```\n\nInserting data with `dict`s via a `DictCursor` instance:\n\n```python\nfrom asynch.cursors import DictCursor\n\nasync def insert_dict():\n    async with conn.cursor(cursor=DictCursor) as cursor:\n        ret = await cursor.execute(\n            \"\"\"INSERT INTO test.asynch(id,decimal,date,datetime,float,uuid,string,ipv4,ipv6) VALUES\"\"\",\n            [\n                {\n                    \"id\": 1,\n                    \"decimal\": 1,\n                    \"date\": \"2020-08-08\",\n                    \"datetime\": \"2020-08-08 00:00:00\",\n                    \"float\": 1,\n                    \"uuid\": \"59e182c4-545d-4f30-8b32-cefea2d0d5ba\",\n                    \"string\": \"1\",\n                    \"ipv4\": \"0.0.0.0\",\n                    \"ipv6\": \"::\",\n                }\n            ],\n        )\n        assert ret == 1\n```\n\nInserting data with `tuple`s:\n\n```python\nasync def insert_tuple():\n    async with conn.cursor(cursor=DictCursor) as cursor:\n        ret = await cursor.execute(\n            \"\"\"INSERT INTO test.asynch(id,decimal,date,datetime,float,uuid,string,ipv4,ipv6) VALUES\"\"\",\n            [\n                (\n                    1,\n                    1,\n                    \"2020-08-08\",\n                    \"2020-08-08 00:00:00\",\n                    1,\n                    \"59e182c4-545d-4f30-8b32-cefea2d0d5ba\",\n                    \"1\",\n                    \"0.0.0.0\",\n                    \"::\",\n                )\n            ],\n        )\n        assert ret == 1\n```\n\n### Connection Pool\n\nBefore the v0.2.4:\n\n```python\nasync def use_pool():\n    pool = await asynch.create_pool()\n    async with pool.acquire() as conn:\n        async with conn.cursor() as cursor:\n            await cursor.execute(\"SELECT 1\")\n            ret = await cursor.fetchone()\n            assert ret == (1,)\n    pool.close()\n    await pool.wait_closed()\n```\n\nSince the v0.2.5 -\u003e v0.3.0:\n\n```python\nasync def use_pool():\n    # init a Pool and fill it with the `minsize` opened connections\n    async with Pool(minsize=1, maxsize=2) as pool:\n        # acquire a connection from the pool\n        async with pool.connection() as conn:\n            async with conn.cursor() as cursor:\n                await cursor.execute(\"SELECT 1\")\n                ret = await cursor.fetchone()\n                assert ret == (1,)\n```\n\nOr, you may opne/close the pool manually:\n\n```python\nasync def use_pool():\n    pool = Pool(minsize=1, maxsize=2)\n    await pool.startup()\n\n    # some logic\n\n    await pool.shutdown()\n```\n\n## ThanksTo\n\n- [clickhouse-driver](https://github.com/mymarilyn/clickhouse-driver), ClickHouse Python Driver with native interface support.\n\n## License\n\nThis project is licensed under the [Apache-2.0](https://github.com/long2ice/asynch/blob/master/LICENSE) License.\n","funding_links":[],"categories":["Python","Language bindings"],"sub_categories":["Python"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flong2ice%2Fasynch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flong2ice%2Fasynch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flong2ice%2Fasynch/lists"}