Your First Object¶
An Object is a handle to a table in ClickHouse. You build one from ordinary
Python values; the data is stored column-wise and the Object references it —
nothing is held in Python memory.
This tutorial runs on the default local backend (embedded chdb + SQLite) — no
servers to start. Every snippet below runs inside a data_context() block,
which owns the lifecycle of the tables you create:
import asyncio
from aaiclick import create_object_from_value
from aaiclick.data.data_context import data_context
async def main():
async with data_context():
... # create and use Objects here
asyncio.run(main())
From a scalar¶
create_object_from_value() infers the type from the value you pass:
obj_scalar_int = await create_object_from_value(42)
print(f"Created from int: {obj_scalar_int}")
print(f"Value: {await obj_scalar_int.data()}\n") # → 42
obj_scalar_float = await create_object_from_value(3.14)
print(f"Created from float: {obj_scalar_float}")
print(f"Value: {await obj_scalar_float.data()}\n") # → 3.14
obj_scalar_str = await create_object_from_value("Hello, ClickHouse!")
print(f"Created from string: {obj_scalar_str}")
print(f"Value: {await obj_scalar_str.data()}") # → Hello, ClickHouse!
await obj.data() pulls the value back into Python.
Always await operation results
Object methods are coroutines. Forgetting await surfaces as a confusing
error downstream, not at the line you forgot.
From a list¶
A list becomes a one-column table, one row per element:
obj_list_int = await create_object_from_value([1, 2, 3, 4, 5])
print(f"Created from int list: {obj_list_int}")
print(f"Values: {await obj_list_int.data()}\n") # → [1, 2, 3, 4, 5]
obj_list_float = await create_object_from_value([1.5, 2.5, 3.5, 4.5])
print(f"Created from float list: {obj_list_float}")
print(f"Values: {await obj_list_float.data()}\n") # → [1.5, 2.5, 3.5, 4.5]
obj_list_str = await create_object_from_value(["apple", "banana", "cherry"])
print(f"Created from string list: {obj_list_str}")
print(f"Values: {await obj_list_str.data()}") # → ['apple', 'banana', 'cherry']
From a dict¶
A dict of arrays becomes a multi-column table — one key per column, one row per
position. data(orient="records") returns rows as a list of dicts:
# Dict of scalars (single row)
obj_dict = await create_object_from_value({"id": 1, "name": "Alice", "age": 30, "score": 95.5})
print(f"Created from dict of scalars: {obj_dict}")
print(f"Values: {await obj_dict.data()}\n") # → {'id': 1, 'name': 'Alice', 'age': 30, 'score': 95.5}
# Dict of arrays (multiple rows)
obj_dict_arrays = await create_object_from_value(
{"id": [1, 2, 3], "name": ["Alice", "Bob", "Charlie"], "age": [30, 25, 35]}
)
print(f"Created from dict of arrays: {obj_dict_arrays}")
# Default: returns first row as dict
first_row = await obj_dict_arrays.data()
print(
f"First row (default): {first_row}"
) # → {'id': [1, 2, 3], 'name': ['Alice', 'Bob', 'Charlie'], 'age': [30, 25, 35]}
# With orient='records': returns all rows as list of dicts
all_rows = await obj_dict_arrays.data(orient=ORIENT_RECORDS)
print(f"All rows (orient='records'): {all_rows}")
Next¶
Operations → — combine Objects with arithmetic, comparison, and bitwise operators.
See Also¶
- Object API — the full surface of
Object - DataContext — lifecycle, scopes, and staleness
- Examples: Basic Operators — the complete runnable script