Skip to main content

Lightweight asynchronous ClickHouse client for Python built on asyncio.

Project description

aiochlite

Lightweight asynchronous ClickHouse client for Python built on aiohttp.

Features

  • Lightweight - minimal dependencies, only aiohttp required
  • Streaming support - efficient processing of large datasets with .stream()
  • External tables - advanced temporary data support
  • Type-safe - full type hints coverage
  • Flexible - custom sessions, compression, query settings

Installation

pip install aiochlite

Quick Start

Basic Connection

from aiochlite import AsyncChClient

# Using context manager (recommended)
async with AsyncChClient(
    url="http://localhost:8123",
    user="default",
    password="",
    database="default"
) as client:
    result = await client.fetch("SELECT 1")

# Or manual connection management
client = AsyncChClient("http://localhost:8123")
try:
    assert await client.ping()
    result = await client.fetch("SELECT 1")
finally:
    await client.close()

Execute Query

await client.execute("""
    CREATE TABLE IF NOT EXISTS users (
        id UInt32,
        name String,
        email String
    ) ENGINE = MergeTree() ORDER BY id
""")

Insert Data

# Insert dictionaries
data = [
    {"id": 1, "name": "Alice", "email": "alice@example.com"},
    {"id": 2, "name": "Bob", "email": "bob@example.com"},
]
await client.insert("users", data)

# Insert tuples
data = [
    (3, "Charlie", "charlie@example.com"),
    (4, "Diana", "diana@example.com"),
]
await client.insert("users", data, column_names=["id", "name", "email"])

# Insert with settings
await client.insert(
    "users",
    [{"id": 5, "name": "Eve", "email": "eve@example.com"}],
    settings={"max_insert_block_size": 100000}
)

Fetch Results

# Fetch all rows
rows = await client.fetch("SELECT * FROM users")
for row in rows:
    print(f"ID: {row.id}, Name: {row.name}, Email: {row.email}")

# Fetch one row
row = await client.fetchone("SELECT * FROM users WHERE id = 1")
if row:
    print(row.name)  # Attribute access
    print(row["name"])  # Dictionary-style access
    print(row.first())  # Get first column value

# Fetch single value
count = await client.fetchval("SELECT count() FROM users")
print(f"Total users: {count}")

# Iterate over results (for large datasets)
async for row in client.stream("SELECT * FROM users"):
    print(row.name)

Query Parameters

result = await client.fetch(
    "SELECT * FROM users WHERE id = {id:UInt32}",
    params={"id": 1}
)

Query Settings

rows = await client.fetch(
    "SELECT * FROM users",
    settings={
        "max_execution_time": 60,
        "max_block_size": 10000
    }
)

External Tables

from aiochlite import ExternalTable

external_data = {
    "temp_data": ExternalTable(
        structure=[("id", "UInt32"), ("value", "String")],
        data=[
            {"id": 1, "value": "foo"},
            {"id": 2, "value": "bar"},
        ]
    )
}

result = await client.fetch(
    """
    SELECT t1.id, t1.name, t2.value
    FROM users t1
    JOIN temp_data t2 ON t1.id = t2.id
    """,
    external_tables=external_data
)

Error Handling

from aiochlite import ChClientError

try:
    await client.execute("SELECT * FROM non_existent_table")
except ChClientError as e:
    print(f"Query failed: {e}")

Custom Session

from aiohttp import ClientSession, ClientTimeout

timeout = ClientTimeout(total=30)
session = ClientSession(timeout=timeout)

async with AsyncChClient(url="http://localhost:8123", session=session) as client:
    result = await client.fetch("SELECT 1")

Enable Compression

async with AsyncChClient(url="http://localhost:8123", enable_compression=True) as client:
    result = await client.fetch("SELECT * FROM users")

License

MIT License

Copyright (c) 2025 darkstussy

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aiochlite-0.1.0.tar.gz (9.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aiochlite-0.1.0-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

Details for the file aiochlite-0.1.0.tar.gz.

File metadata

  • Download URL: aiochlite-0.1.0.tar.gz
  • Upload date:
  • Size: 9.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for aiochlite-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6d3772acf1b3c49ed806a1cd3d3b176421e3dd4a44c848f378faf58d43f09096
MD5 3cb6c2d41914b89c11f7b27649a7b76e
BLAKE2b-256 b067464c165e1d10bf589da022344f4f151416c09028e2bee654b70409940ff8

See more details on using hashes here.

Provenance

The following attestation bundles were made for aiochlite-0.1.0.tar.gz:

Publisher: release.yml on DarkStussy/aiochlite

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file aiochlite-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: aiochlite-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 9.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for aiochlite-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0512f87de169686023b560d9a52203be9f58050d59d08fa9c65f7f4f7970fbd4
MD5 6b9eefbb5060a3f6a91fdcb544f6f53a
BLAKE2b-256 281713b4f3b58ffd29ca1ba8f328a167b14d1a2e8211979388d5ab971e274c92

See more details on using hashes here.

Provenance

The following attestation bundles were made for aiochlite-0.1.0-py3-none-any.whl:

Publisher: release.yml on DarkStussy/aiochlite

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page