跳转至

DuckDB 连接器

DuckDB 是默认的执行引擎,默认版什么都不用装:DuckDB 官方库随下载一起提供,就放在可执行文件旁边,在进程内运行。(精简版是例外,见下方限制一节。)每个执行器按需打开一个连接,结果一次性解码成 Arrow RecordBatch,行数据再从这些批次派生出来——所以 DuckDB 从头到尾都是 Arrow 原生的。会话固定为 UTC(SET GLOBAL TimeZone='UTC'),时间戳不带时区返回,能和其它引擎逐格对齐。

DuckDB 同时是其它连接器的比对基准,这也是 dosi query --execute 没指定连接时会落到它身上的原因。

exec-duckdb feature 控制,默认开启——精简版归档就是关掉它之后的样子。

连接配置

datasources:
  local_duckdb:
    type: duckdb
    uri: duckdb:////absolute/path/warehouse.duckdb

完全不写 uri: 就是内存库。内存库同样支持 execute_batch——在执行器存活期间,状态保留在这条连接上。

参数

类型 必填 默认 说明
type string duckdb
uri string 内存库 duckdb:////abs/path 是绝对路径,duckdb:///rel/path 相对于工作目录,裸文件路径也照收。
default bool false 连接配置

本连接器解析但不使用的键: hostportusernamepassworddatabaseschemasslmodesslrootcertarrow_flight_portcompat_mode。它们能写在这里,是为了让一个文件描述多个数仓,但 DuckDB 执行器从不读它们。

CLI 的 --db <file> 是同一件事的免配置写法:直接把 --execute 指向一个 DuckDB 文件。

Arrow 原生结果

DuckDB 不需要任何配置就走 Arrow——它本身就是原生路径,行结构是从批次里派生的,而不是反过来。它在 REST 和 CLI 两个出口上意味着什么,见 Arrow

已知限制

没有。DuckDB 作为跨引擎基准跑完整个用例集,所以某个表达式在别的引擎上被拒,那是那个引擎的限制,不是模型的问题。

唯一要注意的不是构建细节,而是你下载了哪个版本:精简版不带 libduckdb,本地执行改为调用 PATH 上的 duckdb CLI(JSON 模式,每次查询起一个新进程)。在那个版本上:

  • 必须装有 duckdb CLI,否则 dosi 会报 cannot start duckdb CLI
  • shell-out 路径是针对 DuckDB v1.4.x 系列验证的,发现 CLI 不在该系列时 dosi 会告警一次。那条路径的结果经 JSON 回传,所以类型保真度(大整数、DECIMAL、TIMESTAMPTZ)对版本敏感,进程内的 Arrow 路径没有这个问题;
  • 对内存库做批量执行是 config 错误,因为进程之间什么都不会留下。

本地验证连接

$ dosi query --model $DOSI_EXAMPLES/orders/model.yaml \
    --metrics revenue --group-by orders.status --execute --connection local_duckdb
status     revenue
completed  350
cancelled  100
2 rows

排错

报错 原因与处理
cannot open duckdb database: <e> uri: 指的路径不可写,或者那个文件不是 DuckDB 数据库。用更高版本 DuckDB 写出来的文件也会落在这里。
duckdb rejected SQL: <e> 编译出的 SQL 到了 DuckDB,被 DuckDB 拒了;消息是 DuckDB 自己的。
cannot clone duckdb connection: <e> 底层连接已关闭——通常是数据库文件跑到一半没了。
cannot start duckdb CLI: <e> 只出现在精简版里:装上 DuckDB CLI,或者换成默认版。
in-memory duckdb cannot persist a batch script across calls 同上:把 --db 指向一个文件,别用内存库。

参考链接