@ducklings/ 工人( )
DuckDB WASM 仅供云花板工人使用 httpfs 财务报告和审定财务报表 parquet 静态捆绑。 Async API 拥有完整的 TypeScript 支持.
云纹允许 64 MiB 未按免费和有偿计划对每个工人进行压缩,没有压缩大小限制。 运行
wrangler deploy --dry-run --outdir bundled和你的工人核对Total Upload。选择基于CPU和其他运行时间要求的计划.延期说明: 发表
@ducklings/workers软件包不捆绑 DuckDB 的json在Cloudflare的部署规模预算范围内。 JSON 职能::JSON类型别名,和read_json()因此,标准包中没有。 发表@ducklings/browser软件包由于同样的原因省略了相同的扩展.用来建造以鸭湖为重点的工人
@ducklings/workers-ducklake。 。 。 .
对于 Avro 或 Iceberg 查询, 使用 @ducklings/workers-iceberg,它增加了 httpfs 和 Parquet 的扩展。 从1.5.6起,这些应用程序还必须切换 /wasm 财务报告和审定财务报表 /vite-plugin 进口到那个包裹.
安装
npm install @ducklings/workers
快速启动
import { init, DuckDB } from '@ducklings/workers';
import wasmModule from '@ducklings/workers/wasm';
export default {
async fetch(request: Request): Promise<Response> {
// Initialize with pre-compiled WASM module
await init({ wasmModule });
const db = new DuckDB();
const conn = db.connect();
// All queries are async
const rows = await conn.query<{answer: number}>('SELECT 42 as answer');
conn.close();
db.close();
return Response.json(rows);
}
};
Singleton 初始化(建议)
用于生产、重新使用数据库以及各种请求之间的连接,以避免重新启动间接费用:
import { init, DuckDB, type Connection } from '@ducklings/workers';
import wasmModule from '@ducklings/workers/wasm';
// Global state (reused across requests in the same Worker instance)
let db: DuckDB | null = null;
let conn: Connection | null = null;
let initialized = false;
async function ensureInitialized(): Promise<void> {
if (initialized && db && conn) {
return;
}
await init({ wasmModule });
db = new DuckDB();
conn = db.connect();
initialized = true;
}
export default {
async fetch(request: Request): Promise<Response> {
await ensureInitialized();
const rows = await conn!.query('SELECT 42 as answer');
return Response.json(rows);
}
};
虚拟插件
用于使用 Vite 的项目 @cloudflare/vite-plugin 要构建 Cloudflare Workers, 我们提供一个处理 WASM 文件解析和复制的插件 :
// vite.config.ts
import { defineConfig } from 'vite';
import { cloudflare } from '@cloudflare/vite-plugin';
import { ducklingsWorkerPlugin } from '@ducklings/workers/vite-plugin';
export default defineConfig({
plugins: [
ducklingsWorkerPlugin(),
cloudflare(),
],
});
插件选项
ducklingsWorkerPlugin({
// Name of the WASM file in the output directory (default: 'duckdb-workers.wasm')
wasmFileName: 'duckdb-workers.wasm',
})
插件 :
- 决定:
@ducklings/workers/wasm导入到 wrangler 的相对路径 - 自动将 WASM 文件复制到正确的输出目录( 使用 Cloudflare vite 插件的嵌入式输出结构的工作)
特征
- Async API - 所有查询方法返回承诺
- Base WASM 有同化; 省略 Avro 和 Iceberg
- 内建的 Parquet 和 httpfs 扩展
- 完整 httpfs 支持通过 async
fetch() - 通过 Flechette (query + 插入) 箭头表格支持
- 编写带有类型安全参数的约束的声明
- 交易支持
为什么是单独包?
Cloudflare Workers不支持同步的XMLHttprequest(只使用浏览器的API). 此软件包使用 Emscripten 的 Asyncify 以启用 Async fetch() 调用,使 httpfs 正常工作以装入远程 Parquet 和 CSV 文件,加上 httpfs 写入路径 .
已发布的浏览器和工人软件包不捆绑 json 扩展名。 远程Parquet和CSV访问工作在标准包中. 通过远程 JSON 查询 read_json() 别.
| 软件包 | API 样式 | 大小( gzip) | 网页 |
|---|---|---|---|
@ducklings/browser | Async (网络工人) | ~7.1 米贝 | XMLHttp 请求 |
@ducklings/workers | 同步( 同步) | ~ 12.3 米贝 | 通过聚合获取( ) |
API 密码
初始化
import { init, version } from '@ducklings/workers';
import wasmModule from '@ducklings/workers/wasm';
// Initialize with pre-compiled WASM
await init({ wasmModule });
// Get DuckDB version
console.log(version()); // "v1.4.3"
查询方法( Async)
const conn = db.connect();
// Returns array of objects
const rows = await conn.query<{id: number, name: string}>('SELECT * FROM users');
// Returns Arrow Table (Flechette)
const table = await conn.queryArrow('SELECT * FROM users');
// Execute without returning results
await conn.execute('INSERT INTO users VALUES (1, "Alice")');
// Insert Arrow IPC data into a table
const ipc = tableToIPC(arrowTable, { format: 'stream' });
await conn.insertArrowFromIPCStream('my_table', ipc);
发言稿
const stmt = conn.prepare('SELECT * FROM users WHERE id = ? AND active = ?');
stmt.bindInt32(1, 42);
stmt.bindBoolean(2, true);
const results = await stmt.run(); // Note: async
stmt.close();
远程文件( httpfs)
// Query remote Parquet file
const rows = await conn.query(`
SELECT * FROM 'https://example.com/data.parquet'
LIMIT 10
`);
// Query remote CSV
const csv = await conn.query(`
SELECT * FROM read_csv('https://example.com/data.csv')
`);
read_json(),JSON功能,例如 json_extract(...),则 ::JSON 类型别名在标准工人包中不可用,因为 DuckDB json 扩展名没有捆绑。 标准浏览器包省略了相同的扩展.
R2 密钥
使用 DuckDB 机密访问私有 S3 兼容存储 :
// Cloudflare R2
await conn.execute(`
CREATE SECRET my_r2 (
TYPE R2,
KEY_ID 'your-r2-access-key-id',
SECRET 'your-r2-secret-access-key',
ACCOUNT_ID 'your-cloudflare-account-id'
)
`);
const r2Data = await conn.query(`SELECT * FROM 'r2://bucket/file.parquet'`);
支持的秘密类型 : S3, (中文(简体) ), R2, (中文(简体) ), GCS
对于Cloudflare工人,你可以使用 工人秘密 安全存储证书。 见 实例工作者 (c) 全面执行《公约》.
箭头 IPC 端点
返回查询结果作为箭头 IPC 流以高效传输数据:
import { init, DuckDB, tableToIPC } from '@ducklings/workers';
import wasmModule from '@ducklings/workers/wasm';
export default {
async fetch(request: Request): Promise<Response> {
await init({ wasmModule });
const db = new DuckDB();
const conn = db.connect();
const table = await conn.queryArrow('SELECT * FROM range(1000) t(i)');
const ipcBytes = tableToIPC(table, { format: 'stream' });
conn.close();
db.close();
return new Response(ipcBytes, {
headers: { 'Content-Type': 'application/vnd.apache.arrow.stream' },
});
}
};
交易
// Manual control
await conn.beginTransaction();
try {
await conn.query('INSERT INTO accounts VALUES (1, 1000)');
await conn.commit();
} catch (e) {
await conn.rollback();
throw e;
}
// Or use the wrapper (auto-rollback on error)
await conn.transaction(async () => {
await conn.query('INSERT INTO orders VALUES (...)');
return 'success';
});
箭头支持
import { tableFromArrays, tableFromIPC, tableToIPC, utf8 } from '@ducklings/workers';
// Query as Arrow Table
const table = await conn.queryArrow('SELECT * FROM users');
// Build Arrow tables
const custom = tableFromArrays({
id: [1, 2, 3],
name: ['Alice', 'Bob', 'Charlie']
});
// Serialize/deserialize Arrow IPC
const bytes = tableToIPC(table, { format: 'stream' });
const restored = tableFromIPC(bytes);
// Insert Arrow IPC data directly into a table
const data = tableFromArrays(
{ id: [1, 2], label: ['x', 'y'] },
{ types: { label: utf8() } } // Use plain utf8 (see note below)
);
const ipc = tableToIPC(data, { format: 'stream' });
await conn.insertArrowFromIPCStream('my_table', ipc);
词典编码 : 弗莱歇特的
tableFromArrays()默认为dictionary(utf8())用于字符串列。 内部使用的Arrow IPC解码器不支持词典编码流. 建表格时insertArrowFromIPCStream(),明确设置字符串列为utf8()数字 :import { utf8 } from '@ducklings/workers'; tableFromArrays({ col: ['a', 'b'] }, { types: { col: utf8() } });
浏览器使用
对于浏览器环境, 使用 @ducklings/browser 而不是在网络工作员中运行查询.
限制
- 没有动态扩展装入:只有静态编译扩展可用. 默认工人建筑包括Parquet和httpfs. Avro, Iceberg, DuckLake, Space, 和JSON没有捆绑.
INSTALL编号 :LOAD用于其他扩展的命令不会工作.
许可证
麻省理工学院