Skip to main content 首页 创作者 comeonoliver skillshub clickhouse-sdk-patterns
clickhouse-sdk-patterns Production-ready patterns for @clickhouse/client — streaming inserts, typed queries,
error handling, and connection management.
Use when building robust ClickHouse integrations, implementing streaming,
or establishing team coding standards.
Trigger: "clickhouse SDK patterns", "clickhouse client patterns",
"clickhouse best practices", "clickhouse streaming insert".
跳到安装 Skills Marketplace 发现并探索由社区构建的 Agent Skills
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/ComeOnOliver/skillshub --skill clickhouse-sdk-patterns命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
下载 Zip 下载中... name clickhouse-sdk-patterns description Production-ready patterns for @clickhouse/client — streaming inserts, typed queries,
error handling, and connection management.
Use when building robust ClickHouse integrations, implementing streaming,
or establishing team coding standards.
Trigger: "clickhouse SDK patterns", "clickhouse client patterns",
"clickhouse best practices", "clickhouse streaming insert".
allowed-tools Read, Write, Edit version 1.0.0 license MIT author Jeremy Longshore <jeremy@intentsolutions.io> tags ["saas","database","analytics","clickhouse","olap"] compatible-with claude-code
ClickHouse SDK Patterns
Overview
Production patterns for @clickhouse/client — typed queries, streaming inserts,
error handling, and connection lifecycle management.
Prerequisites
@clickhouse/client installed (see clickhouse-install-auth)
Familiarity with async/await and Node.js streams
Instructions
Pattern 1: Typed Query Helper
import { createClient } from '@clickhouse/client' ;
const client = createClient ({
url : process.env .CLICKHOUSE_HOST !,
username : process.env .CLICKHOUSE_USER ?? 'default' ,
password : process.env .CLICKHOUSE_PASSWORD ?? '' ,
});
async function query<T>(sql : string , params ?: Record <string , unknown >): Promise <T[]> {
const rs = await client.query ({
query : sql,
query_params : params,
format : 'JSONEachRow' ,
});
return rs.json <T>();
}
interface EventCount {
event_type : string ;
cnt : ;
}
rows = query< >(
,
{ : }
);
string
const
await
EventCount
'SELECT event_type, count() AS cnt FROM events WHERE user_id = {user_id:UInt64} GROUP BY event_type'
user_id
42
Note on parameterized queries: ClickHouse uses {name:Type} syntax for parameters,
not $1 or ?. Always use typed parameters to prevent SQL injection.
Pattern 2: Streaming Insert (Backpressure-Safe) import { createClient } from '@clickhouse/client' ;
import { Readable } from 'stream' ;
async function streamInsert (rows : AsyncIterable <Record <string , unknown >> ) {
const stream = new Readable ({
objectMode : true ,
read ( ) {},
});
const insertPromise = client.insert ({
table : 'events' ,
values : stream,
format : 'JSONEachRow' ,
});
for await (const row of rows) {
if (!stream.push (row)) {
await new Promise <void >((resolve ) => stream.once ('drain' , resolve));
}
}
stream.push (null );
await insertPromise;
}
Pattern 3: Batch Insert with Retry async function batchInsert<T extends Record <string , unknown >>(
table : string ,
rows : T[],
batchSize = 10_000 ,
maxRetries = 3 ,
): Promise <{ inserted : number ; errors : Error [] }> {
let inserted = 0 ;
const errors : Error [] = [];
for (let i = 0 ; i < rows.length ; i += batchSize) {
const batch = rows.slice (i, i + batchSize);
let attempt = 0 ;
while (attempt < maxRetries) {
try {
await client.insert ({
table,
values : batch,
format : 'JSONEachRow' ,
});
inserted += batch.length ;
break ;
} catch (err) {
attempt++;
if (attempt === maxRetries) {
errors.push (err as Error );
} else {
await new Promise ((r ) => setTimeout (r, 1000 * Math .pow (2 , attempt)));
}
}
}
}
return { inserted, errors };
}
Pattern 4: Streaming SELECT (Low Memory)
async function * streamQuery<T>(sql : string ): AsyncGenerator <T> {
const rs = await client.query ({ query : sql, format : 'JSONEachRow' });
const stream = rs.stream ();
for await (const rows of stream) {
for (const row of rows) {
yield (row as { json : () => T }).json ();
}
}
}
for await (const event of streamQuery<{ event_type : string }>('SELECT * FROM events' )) {
process.stdout .write (`${event.event_type} \n` );
}
Pattern 5: Error Handling import { ClickHouseError } from '@clickhouse/client' ;
async function safeQuery<T>(sql : string ): Promise <{ data : T[] | null ; error : string | null }> {
try {
const rs = await client.query ({ query : sql, format : 'JSONEachRow' });
return { data : await rs.json <T>(), error : null };
} catch (err) {
if (err instanceof ClickHouseError ) {
console .error (`ClickHouse error ${err.code} : ${err.message} ` );
return { data : null , error : `CH-${err.code} : ${err.message} ` };
}
console .error ('Client error:' , (err as Error ).message );
return { data : null , error : (err as Error ).message };
}
}
Pattern 6: Connection Lifecycle
process.on ('SIGTERM' , async () => {
console .log ('Closing ClickHouse connection...' );
await client.close ();
process.exit (0 );
});
async function isHealthy ( ): Promise <boolean > {
try {
const { success } = await client.ping ();
return success;
} catch {
return false ;
}
}
Pattern 7: ClickHouse Settings Per Query
const rs = await client.query ({
query : 'SELECT * FROM huge_table' ,
format : 'JSONEachRow' ,
clickhouse_settings : {
max_threads : 4 ,
max_memory_usage : 1_000_000_000 ,
max_execution_time : 30 ,
max_result_rows : 100_000 ,
},
});
Format Reference Format Use Case Streaming JSONEachRowStandard JSON rows (NDJSON) Yes JSONCompactEachRowArrays instead of objects (smaller) Yes CSVExport/import Yes TabSeparatedCLI-compatible output Yes ParquetAnalytics interchange Yes NativeFastest binary format Yes
Error Handling Error Code Meaning Action SYNTAX_ERROR (62)Bad SQL Fix query syntax UNKNOWN_TABLE (60)Table doesn't exist Check table name, database TOO_MANY_SIMULTANEOUS_QUERIES (202)Connection overload Reduce concurrency or pool MEMORY_LIMIT_EXCEEDED (241)Query uses too much RAM Add filters, use streaming TIMEOUT_EXCEEDED (159)Query too slow Optimize ORDER BY, add indexes
Resources
Next Steps Apply these patterns in clickhouse-core-workflow-a for real data modeling.