免责声明: 这是一个个人项目。它 与任何雇主或供应商均无关联,未获其认可或支持。不提供任何保证—— 使用风险自负。
duckrun 在 DuckDB 中运行 SQL,并通过 delta-rs 读写 Delta Lake —— 支持本地或 OneLake / S3 / GCS / ADLS。它只是胶水层:DuckDB 执行 · delta-rs 物化 · Arrow 桥接 · dbt 编排。有两种使用方式:
connect()—— 一个笔记本辅助工具,可直接通过 SQL 查询和写入 Delta(即本页内容);- 一个 dbt 适配器,将模型物化为 Delta 表。
并发写入是一等公民:每次写入都固定到快照,并大声失败,而不是 静默交错。
安装
在 Microsoft Fabric 笔记本中,升级并重启内核(duckrun 需要 duckdb ≥ 1.5.4,
这比捆绑的稳定版更新;否则在 connect() 时会大声失败):
!pip install duckrun --upgrade
notebookutils.session.restartPython()
快速入门 — 在笔记本中使用 OneLake
import duckrun
# Read-only by default — explore a lakehouse safely, no chance of an accidental write.
# Use the workspace + lakehouse GUIDs (friendly names hit an upstream OneLake read bug for now).
conn = duckrun.connect("abfss://<workspace_id>@onelake.dfs.fabric.microsoft.com/<lakehouse_id>/Tables/dbo")
conn.sql("SHOW TABLES").show()
conn.sql("select status, count(*) from orders group by status").show()
conn.sql("select * from orders").df() # native DuckDB relation → pandas (.arrow(), .pl() too)
# Time travel: read an older version with delta_scan(…, version => N)
conn.sql("select * from delta_scan('.../Tables/dbo/orders', version => 0)").show()
需要编写?使用 read_only=False 进行配置 — 一切皆为 SQL:
conn = duckrun.connect("abfss://…/Tables/dbo", read_only=False)
# write Delta straight from SQL — CREATE TABLE AS routes to delta-rs
conn.sql("CREATE OR REPLACE TABLE clean_orders AS SELECT * FROM orders WHERE amount > 0")
# raw DML routes to delta-rs (insert / update / delete / alter / drop)
conn.sql("delete from clean_orders where amount = 0")
# upsert — snapshot-pinned automatically, nothing extra to pass
conn.sql("""
MERGE INTO clean_orders t USING updates s ON t.id = s.id
WHEN MATCHED THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *
""")
conn.close()
多个目录 — 附加更多 Lakehouse,并通过三段式名称跨目录读取/连接。在
Fabric 中,Warehouse 只是一个写锁定的 Lakehouse,因此将其附加在可写
Lakehouse 旁边 read_only=True:
conn.attach("abfss://…/warehouse.Warehouse/Tables", name="warehouse", read_only=True)
conn.attach("/data/reference", name="local")
conn.sql("select * from warehouse.mart.facts f join local.dbo.lookup l on l.id = f.id").show()
对本地路径同样适用,s3://、gs:// 或 az://。完整方法映射:
Connection API · API reference ·
live multi-catalog demo。
dbt adapter
duckrun 也是一个 dbt adapter —— 一个围绕
dbt-duckdb 的轻量封装,增加了基于 Delta 的 table / incremental
materializations(dbt-duckdb 提供的其他所有内容均被继承)。将 profile 指向一个 lakehouse
并 dbt run:
# ~/.dbt/profiles.yml
my_project:
outputs:
dev:
type: duckrun
root_path: "abfss://<workspace_id>@onelake.dfs.fabric.microsoft.com/<lakehouse_id>/Tables"
在一个项目中配置多个湖仓 — 将额外的写入根声明为命名 catalogs:,并使用标准的 dbt +database: <alias> 配置将模型发送到其中一个(例如,跨三个 Fabric Lakehouse 的 Bronze/Silver/Gold 奖牌架构)。ref() 和 join 可在它们之间解析:
dev:
type: duckrun
root_path: "abfss://ws@onelake.dfs.fabric.microsoft.com/LH_Silver.Lakehouse/Tables" # default
catalogs:
lh_bronze: { root_path: "abfss://ws@onelake.dfs.fabric.microsoft.com/LH_Bronze.Lakehouse/Tables" }
lh_gold: { root_path: "abfss://ws@onelake.dfs.fabric.microsoft.com/LH_Gold.Lakehouse/Tables" }
-- models/bronze/raw_events.sql → lands in LH_Bronze
{{ config(materialized='incremental', database='lh_bronze', unique_key='id') }}
select ...
配置文件、物化、增量策略(merge、insert、append、delete+insert、microbatch)、源, 以及自动压缩/vacuum 均位于 docs/dbt-adapter.md。
调试模型
当模型运行但数值不正确时,使用 dbt 对其进行编译并获取一个 DuckDB 关系——
真实类型、惰性、只读。由于适配器在进程内运行 DuckDB,dbt 只需编译;
duckrun 负责执行。没有 dbt show JSON 往返,因此无需为每列猜测类型。
from duckrun import dbt_project
p = dbt_project("dbt/", target="dev")
p.show("orders_enriched").filter("customer = 'X'").limit(100) # pushes into the delta_scan
p.sql("select * from {{ ref('stg_orders') }} where year = 2026")
# run the model one CTE at a time to find where the row count goes wrong
p.ctes("orders_enriched") # ['base', 'allocated', 'final']
p.cte("orders_enriched", "allocated").count("*")
更多 — CTE 切片,即你正在查看的 is_incremental() 分支,临时模型,以及为什么
会话无法写入 — 详见 docs/dbt-debug.md。
在真实项目中查看:aemo 和 coffee 是
可运行的入门项目,而 parity_tests/ 在 duckrun 上运行真实的 type: duckdb 项目(jaffle_shop、
sde、MRR、TechFlow、Tuva),且保持原样 — 包括它们自身的测试。
使用 AI 助手构建
duckrun 附带一份指南,以便 AI 编码助手正确获取适配器的默认设置(其中几项与 其他 dbt 适配器不同)。对于 Claude Code:
/plugin marketplace add djouallah/duckrun
/plugin install duckrun-projects@duckrun
其他助手读取仓库根目录下的 AGENTS.md,它指向完整的指南。
使用 duckrun 不需要这些。
贡献
欢迎提交 Bug 报告和 PR — 请参阅 CONTRIBUTING.md 了解流程(分支、
PR、哪些 CI 检查实际作为门禁)以及简短的规则列表。
文档
其他所有内容 — 架构、快照隔离、一致性测试结果、基准测试 — 都在 文档站点上:djouallah.github.io/duckrun。
许可证
MIT