asynch


Nameasynch JSON
Version 0.2.5 PyPI version JSON
download
home_pagehttps://github.com/long2ice/asynch
SummaryAn asyncio driver for ClickHouse with native TCP support
upload_time2024-10-17 08:24:35
maintainerNone
docs_urlNone
authorlong2ice
requires_python<4.0,>=3.9
licenseApache-2.0
keywords asyncio clickhouse python driver
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # asynch

![pypi](https://img.shields.io/pypi/v/asynch.svg?style=flat)
![license](https://img.shields.io/github/license/long2ice/asynch)
![workflows](https://github.com/long2ice/asynch/workflows/pypi/badge.svg)
![workflows](https://github.com/long2ice/asynch/workflows/ci/badge.svg)

## Introduction

`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/).

## Installation

```shell
> pip install asynch
```

If you want to install [`clickhouse-cityhash`](https://pypi.org/project/clickhouse-cityhash/) to enable transport compression

```shell
> pip install asynch[compression]
```

## Usage

Basically, a connection to a ClickHouse server can be established in two ways:

1. with a DSN string, e.g., `clickhouse://[user:password]@host:port/database`;

    ```python
    from asynch import connect

    # connecting with a DSN string
    async def connect_database():
        conn = await connect(
            dsn = "clickhouse://ch_user:P@55w0rD:@127.0.0.1:9000/chdb",
        )
    ```

2. with separately given connection/DSN parameters: `user` (optional), `password` (optional), `host`, `port`, `database`.

    ```python
    from asynch import connect

    # connecting with DSN parameters
    async def connect_database():
        conn = await connect(
            user = "ch_user",
            password = "P@55w0rD",
            host = "127.0.0.1",
            port = 9000,
            database = "chdb",
        )
    ```

If a DSN string is given, it takes priority over any specified connection parameter.

Create 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.

```python
async def create_table(conn: Connection):
    async with conn.cursor(cursor=DictCursor) as cursor:
        await cursor.execute("CREATE DATABASE IF NOT EXISTS test")
        await cursor.execute("""
        CREATE TABLE if not exists test.asynch
        (
            `id`       Int32,
            `decimal`  Decimal(10, 2),
            `date`     Date,
            `datetime` DateTime,
            `float`    Float32,
            `uuid`     UUID,
            `string`   String,
            `ipv4`     IPv4,
            `ipv6`     IPv6
        )
        ENGINE = MergeTree
        ORDER BY id
        """
        )
```

Fetching one row from an executed SQL statement:

```python
async def fetchone(conn: Connection):
    # by default, an instance of the `Cursor` class
    async with conn.cursor() as cursor:
        await cursor.execute("SELECT 1")
        ret = await cursor.fetchone()
        assert ret == (1,)
```

Fetching all the rows from an executed SQL statement:

```python
async def fetchall():
    async with conn.cursor() as cursor:
        await cursor.execute("SELECT 1")
        ret = await cursor.fetchall()
        assert ret == [(1,)]
```

Using an instance of the `DictCursor` class to get results as a sequence of `dict`ionaries representing the rows of an executed SQL query:

```python
async def dict_cursor():
    async with conn.cursor(cursor=DictCursor) as cursor:
        await cursor.execute("SELECT 1")
        ret = await cursor.fetchall()
        assert ret == [{"1": 1}]
```

Inserting data with `dict`s via a `DictCursor` instance:

```python
from asynch.cursors import DictCursor

async def insert_dict():
    async with conn.cursor(cursor=DictCursor) as cursor:
        ret = await cursor.execute(
            """INSERT INTO test.asynch(id,decimal,date,datetime,float,uuid,string,ipv4,ipv6) VALUES""",
            [
                {
                    "id": 1,
                    "decimal": 1,
                    "date": "2020-08-08",
                    "datetime": "2020-08-08 00:00:00",
                    "float": 1,
                    "uuid": "59e182c4-545d-4f30-8b32-cefea2d0d5ba",
                    "string": "1",
                    "ipv4": "0.0.0.0",
                    "ipv6": "::",
                }
            ],
        )
        assert ret == 1
```

Inserting data with `tuple`s:

```python
async def insert_tuple():
    async with conn.cursor(cursor=DictCursor) as cursor:
        ret = await cursor.execute(
            """INSERT INTO test.asynch(id,decimal,date,datetime,float,uuid,string,ipv4,ipv6) VALUES""",
            [
                (
                    1,
                    1,
                    "2020-08-08",
                    "2020-08-08 00:00:00",
                    1,
                    "59e182c4-545d-4f30-8b32-cefea2d0d5ba",
                    "1",
                    "0.0.0.0",
                    "::",
                )
            ],
        )
        assert ret == 1
```

### Connection Pool

Before the v0.2.4:

```python
async def use_pool():
    pool = await asynch.create_pool()
    async with pool.acquire() as conn:
        async with conn.cursor() as cursor:
            await cursor.execute("SELECT 1")
            ret = await cursor.fetchone()
            assert ret == (1,)
    pool.close()
    await pool.wait_closed()
```

Since the v0.2.5:

```python
async def use_pool():
    # init a Pool and fill it with `minsize` opened connections
    async with Pool(minsize=1, maxsize=2) as pool:
        # acquire a connection from the pool
        async with pool.connection() as conn:
            async with conn.cursor() as cursor:
                await cursor.execute("SELECT 1")
                ret = await cursor.fetchone()
                assert ret == (1,)
```

## ThanksTo

- [clickhouse-driver](https://github.com/mymarilyn/clickhouse-driver), ClickHouse Python Driver with native interface support.

## License

This project is licensed under the [Apache-2.0](https://github.com/long2ice/asynch/blob/master/LICENSE) License.


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/long2ice/asynch",
    "name": "asynch",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.9",
    "maintainer_email": null,
    "keywords": "asyncio, clickhouse, python, driver",
    "author": "long2ice",
    "author_email": "long2ice@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/67/e7/c759d9202de046b2ca280fbfc1524063988f90ad8d4ee7a805ca7140c86e/asynch-0.2.5.tar.gz",
    "platform": null,
    "description": "# 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> 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> pip install asynch[compression]\n```\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 connect\n\n    # connecting with a DSN string\n    async def connect_database():\n        conn = await connect(\n            dsn = \"clickhouse://ch_user:P@55w0rD:@127.0.0.1:9000/chdb\",\n        )\n    ```\n\n2. with separately given connection/DSN parameters: `user` (optional), `password` (optional), `host`, `port`, `database`.\n\n    ```python\n    from asynch import connect\n\n    # connecting with DSN parameters\n    async def connect_database():\n        conn = await connect(\n            user = \"ch_user\",\n            password = \"P@55w0rD\",\n            host = \"127.0.0.1\",\n            port = 9000,\n            database = \"chdb\",\n        )\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:\n\n```python\nasync def use_pool():\n    # init a Pool and fill it with `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\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\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "An asyncio driver for ClickHouse with native TCP support",
    "version": "0.2.5",
    "project_urls": {
        "Documentation": "https://github.com/long2ice/asynch",
        "Homepage": "https://github.com/long2ice/asynch",
        "Repository": "https://github.com/long2ice/asynch.git"
    },
    "split_keywords": [
        "asyncio",
        " clickhouse",
        " python",
        " driver"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "266a5b164cf1cb69809484b747e20fcd17493ef57921c69fae6593197423c8fb",
                "md5": "3aad41cc8c05af88af1d5a6565d55b2d",
                "sha256": "b14a4d4f49c3ed2f77a44722ce33a48b8049acb1ba24f425792ffdb3d1ef2829"
            },
            "downloads": -1,
            "filename": "asynch-0.2.5-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "3aad41cc8c05af88af1d5a6565d55b2d",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.9",
            "size": 81300,
            "upload_time": "2024-10-17T08:24:33",
            "upload_time_iso_8601": "2024-10-17T08:24:33.484310Z",
            "url": "https://files.pythonhosted.org/packages/26/6a/5b164cf1cb69809484b747e20fcd17493ef57921c69fae6593197423c8fb/asynch-0.2.5-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "67e7c759d9202de046b2ca280fbfc1524063988f90ad8d4ee7a805ca7140c86e",
                "md5": "d16555cc0ef486f3d1b4dfc5cba5c8e1",
                "sha256": "e8e1656c81a1a156df20334e4c08d5832b02f38166dffc979235336309608543"
            },
            "downloads": -1,
            "filename": "asynch-0.2.5.tar.gz",
            "has_sig": false,
            "md5_digest": "d16555cc0ef486f3d1b4dfc5cba5c8e1",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.9",
            "size": 59288,
            "upload_time": "2024-10-17T08:24:35",
            "upload_time_iso_8601": "2024-10-17T08:24:35.366418Z",
            "url": "https://files.pythonhosted.org/packages/67/e7/c759d9202de046b2ca280fbfc1524063988f90ad8d4ee7a805ca7140c86e/asynch-0.2.5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-10-17 08:24:35",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "long2ice",
    "github_project": "asynch",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "asynch"
}
        
Elapsed time: 0.35295s