manus-skills/.kortix/opencode/skills/data/chdb-datastore/references/api-reference.md
zhukang 1c7abd81d1 All 310 Manus skill-hub community skills as a Kortix marketplace registry
- 310 registry:skill items, 1528 files, 7 categories (hub tags)
- registry.json generated by @kortix/registry buildRegistry
- nested SKILL.md in sn-da-* renamed SUBSKILL.md (no phantom skills)
- provenance + licenses: SOURCES.md
2026-09-15 13:37:20 +08:00

8.6 KiB

DataStore API Reference

Complete method signatures for the DataStore class. DataStore provides a pandas-compatible API backed by ClickHouse.

Table of Contents


Import & Construction

from datastore import DataStore
# or: from chdb.datastore import DataStore
# or: import chdb.datastore as pd  (drop-in replacement)

Constructor

DataStore(source=None, table=None, database=":memory:", connection=None, **kwargs)
Source type Usage
dict DataStore({'col1': [1, 2], 'col2': ['a', 'b']})
pd.DataFrame DataStore(df)
str (source type) DataStore("file", path="data.parquet")
str (source type) DataStore("mysql", host="host:3306", database="db", table="t", user="u", password="p")

Factory Methods

See connectors.md for all factory methods (from_file, from_mysql, from_s3, uri, etc.).


Selection & Filtering

Expression Returns Description
ds['col'] LazySeries Single column
ds[['c1', 'c2']] DataStore Multiple columns
ds[condition] DataStore Boolean filter (e.g., ds[ds['age'] > 25])
.select(*fields) DataStore SQL-style SELECT with expressions
.filter(condition) DataStore SQL-style WHERE clause
.where(condition) DataStore Mask values where condition is False (pandas semantics)
result = ds[ds["age"] > 25]
result = ds[(ds["status"] == "active") & (ds["revenue"] > 1000)]
result = ds[["name", "city", "revenue"]]
result = ds.select("name", "revenue * 1.1 AS adjusted_revenue")
result = ds.filter(ds["country"] == "US")
result = ds.where(ds["age"] > 25)  # keeps all rows; non-matching values become NaN

Sorting & Limiting

Method Description
.sort_values(by, ascending=True) Pandas-style sort (by can be str or list)
.sort(*columns, ascending=True) SQL-style ORDER BY
.orderby(*columns, ascending=True) Alias for .sort()
.limit(n) LIMIT n rows
.offset(n) Skip first n rows
.head(n=5) First n rows
.tail(n=5) Last n rows
result = ds.sort_values("revenue", ascending=False)
result = ds.sort_values(["country", "city"])
result = ds.head(10)
result = ds.limit(100).offset(50)

GroupBy & Aggregation

grouped = ds.groupby(*columns)          # returns LazyGroupBy
grouped = ds.groupby("dept")
grouped = ds.groupby(["region", "product"])
Method Description
.agg(func=None, **kwargs) Aggregate with named functions
.sum(), .mean(), .count(), .min(), .max() Single aggregation
.std(), .var() Standard deviation / variance
.having(condition) HAVING clause (after aggregation)
result = ds.groupby("dept")["salary"].mean()
result = ds.groupby("dept").agg({"salary": "mean", "bonus": "sum"})
result = ds.groupby(["region", "product"]).agg(
    total_revenue=("revenue", "sum"),
    avg_quantity=("quantity", "mean"))

Joins

.join(other, on=None, how='inner', left_on=None, right_on=None, suffixes=('_x', '_y'))
.merge(other, on=None, how='inner')
how Description
'inner' Only matching rows (default)
'left' All left rows + matching right
'right' All right rows + matching left
'outer' All rows from both sides
'cross' Cartesian product
result = orders.join(customers, left_on="customer_id", right_on="id")
result = orders.join(customers, on="customer_id", how="left")
result = ds1.merge(ds2, on="key", how="outer")

Cross-source joins work transparently — join a MySQL table with a Parquet file:

mysql_ds = DataStore.from_mysql(host="db:3306", database="crm", table="users", user="root", password="pass")
parquet_ds = DataStore.from_file("orders.parquet")
result = mysql_ds.join(parquet_ds, left_on="id", right_on="user_id")

Mutation

Method Description
.assign(**kwargs) Add computed columns
.with_column(name, expr) Add single column
.drop(columns) Remove columns (str or list)
.rename(columns={}) Rename columns via mapping
.fillna(value) Fill NaN/NULL values
.dropna(subset=None) Drop rows with NaN/NULL
.distinct(subset=None, keep='first') Deduplicate rows
result = ds.assign(
    profit=ds["revenue"] - ds["cost"],
    margin=lambda x: x["profit"] / x["revenue"])
result = ds.drop("temp_column")
result = ds.rename(columns={"old_name": "new_name"})
result = ds.fillna(0)
result = ds.dropna(subset=["email", "phone"])
result = ds.distinct(subset=["user_id"], keep="first")

String Accessor (.str)

Access via ds['column'].str.*. 56 methods available, including:

Method Description
.str.upper(), .str.lower() Case conversion
.str.strip(), .str.lstrip(), .str.rstrip() Whitespace trimming
.str.contains(pattern) Substring/regex match → boolean
.str.startswith(prefix), .str.endswith(suffix) Prefix/suffix check
.str.replace(old, new) String replacement
.str.split(sep) Split into parts
.str.len() String length
.str.slice(start, stop) Substring extraction
.str.cat(sep=None) Concatenation
.str.extract(pattern) Regex group extraction
.str.pad(width), .str.zfill(width) Padding
.str.match(pattern) Full regex match
ds["name"].str.upper()
ds["email"].str.contains("@gmail")
ds["code"].str.slice(0, 3)

DateTime Accessor (.dt)

Access via ds['column'].dt.*. 42+ methods available, including:

Property/Method Description
.dt.year, .dt.month, .dt.day Date components
.dt.hour, .dt.minute, .dt.second Time components
.dt.dayofweek, .dt.dayofyear Day ordinals
.dt.quarter Quarter (1-4)
.dt.date, .dt.time Date/time part
.dt.strftime(format) Format as string
.dt.floor(freq), .dt.ceil(freq) Round to frequency
.dt.tz_localize(tz), .dt.tz_convert(tz) Timezone handling
.dt.normalize() Reset time to midnight
ds["order_date"].dt.year
ds["order_date"].dt.month
ds["timestamp"].dt.hour
ds["created_at"].dt.strftime("%Y-%m-%d")

Inspection & Execution Triggers

These properties/methods trigger execution of the lazy query:

Property/Method Returns Description
.columns list Column names
.shape (rows, cols) Dimensions
.dtypes dict Column types
.head(n=5) DataStore First n rows
.tail(n=5) DataStore Last n rows
.describe() DataStore Summary statistics
.info() None Print DataFrame info
print(ds) — Display results
len(ds) int Row count
for row in ds — Iterate rows
.equals(other) bool Compare DataStores

These methods do not trigger execution:

Method Returns Description
.to_sql() str View the generated SQL
.explain() str Execution plan
print(ds.columns)          # → ['name', 'age', 'city']
print(ds.shape)            # → (1000, 3)
print(ds.to_sql())         # → SELECT ... FROM ... WHERE ...
print(ds.describe())       # → statistics table

Writing Data

Use the insert_into / select_from pattern:

source = DataStore.from_mysql(host="db:3306", database="shop", table="orders", user="root", password="pass")
target = DataStore("file", path="output.parquet", format="Parquet")

target.insert_into("col1", "col2").select_from(
    source.select("col1", "col2").filter(source['value'] > 100)
).execute()

Configuration

from datastore import config

config.use_chdb()           # force chDB/SQL backend
config.use_pandas()         # force pandas backend
config.prefer_chdb()        # prefer chDB when possible, fallback to pandas
config.prefer_pandas()      # prefer pandas when possible, fallback to chDB
config.enable_debug()       # verbose logging (shows generated SQL)
config.enable_profiling()   # performance profiling