首页
/ Ghost Tinybird Copy Pipe 编写规范:定时导出数据管道的约定、语法与示例解析

Ghost Tinybird Copy Pipe 编写规范:定时导出数据管道的约定、语法与示例解析

2026-09-07 17:47:48作者:房伟宁

本文围绕 Ghost 仓库中 copy-files.md 这份 Tinybird 规则文件展开,完整覆盖它对 Copy Pipe 文件的全部编写约定(创建位置、必备键、copy_mode 取值等),并结合 tinybird skill 的 SKILL.md、同目录下的 pipe-files.mdmaterialized-files.mdsink-files.md 以及仓库内真实的 .pipe 文件,解析示例中每个键的含义与取值,读完你可以直接按 Ghost 的规范写出一个合法的 COPY 类型管道文件。

一、规则文件的定位:Ghost 的 Tinybird 项目本地文件体系

Ghost 的 Web 流量分析由 Tinybird 支撑。docs/codebase/post-analytics.md 中明确写道:"Web traffic comes from Ghost's Tinybird integration"。对应的 Tinybird 项目本地文件集中在 ghost/core/core/server/data/tinybird/ 目录下,按资源类型分放在 pipes/endpoints/ 等子目录中,当前仓库共有 35 个 .pipe 文件与 5 个 .datasource 文件。

在这个体系之上,仓库为 AI Agent 与开发者沉淀了一套 Tinybird 最佳实践技能,即 .agents/skills/tinybird/SKILL.md。该 skill 声明了适用场景(创建或更新 .datasource.pipe.connection 资源、编写或优化 SQL、设计 endpoint schema 与数据模型、处理物化视图或 copy pipes 等),并在 "Rule Files" 一节中列出了全部规则文件清单,其中就包括本文主题的 rules/copy-files.md(同列的还有 pipe-files.mdmaterialized-files.mdsink-files.mdsql.mdendpoint-optimization.mdtests.md 等)。

从源码结构看,skill 把管道文件按 TYPE 拆成了四类规范:endpoint(默认查询型)、materialized(物化视图)、sink(外部系统导出)、copy(定时复制到另一数据源)。copy-files.md 就是第四类的约定文件。

二、Copy Pipe 的核心编写约定

copy-files.md 全文由 6 条规则和 1 个完整示例构成,逐条含义如下:

约定 原文规则 说明
按需创建 "Do not create by default unless requested." Copy Pipe 属于非默认资源,只有在明确需要时才新建,与 materialized、sink 两类规则中的同款措辞一致
目录位置 "Create under /copies." 新建文件统一放在 Tinybird 项目的 /copies 目录下,与 pipes/endpoints/ 等目录同级组织
调度键节制 "Do not include COPY_SCHEDULE unless explicitly requested." 不主动添加调度键,仅当明确需要定时触发时写入
必备键 "Use TYPE COPY and TARGET_DATASOURCE." 文件必须声明 TYPE COPY 并通过 TARGET_DATASOURCE 指定复制目标数据源
copy_mode 取值 "The default copy_mode is append; but it's better if you set it explicitly. The other option is replace" 默认行为是 append,但规则建议显式声明;另一可选值为 replace
语法示例 见下文示例 给出一个带模板参数的完整 COPY 管道文件

其中两个键的语义值得展开:

  • TYPE COPY:声明该管道为复制型管道,与 TYPE MATERIALIZEDTYPE SINKTYPE endpoint 并列。pipe-files.md 也印证了这一点,它规定允许的 TYPE 值就是 endpointcopymaterializedsink 四种。
  • TARGET_DATASOURCE:复制的目标数据源名称。对比 materialized-files.md 可以发现命名差异——物化管道写的是 DATASOURCE <name>,而复制管道写的是 TARGET_DATASOURCE <name>,前者是物化结果落地表,后者强调"复制到哪里"。
  • COPY_SCHEDULE:cron 表达式,决定管道按什么周期执行复制。示例中 COPY_SCHEDULE 0 * * * * 表示每小时整点执行一次。
  • COPY_MODEappend 表示每次执行向目标数据源追加新行,replace 表示替换目标数据。规则建议即使打算用默认的 append 也要显式写出,避免依赖隐式默认值。

三、完整示例逐行解析

copy-files.md 给出的标准示例如下(原文完整保留):

DESCRIPTION Copy Pipe to export sales hour every hour to the sales_hour_copy Data Source

NODE daily_sales
SQL >
    %
    SELECT toStartOfDay(starting_date) day, country, sum(sales) as total_sales
    FROM teams
    WHERE day BETWEEN toStartOfDay(now()) - interval 1 day AND toStartOfDay(now())
    and country = {{ String(country, 'US')}}
    GROUP BY day, country

TYPE COPY
TARGET_DATASOURCE sales_hour_copy
COPY_SCHEDULE 0 * * * *
COPY_MODE append

按管道文件语法逐段解读:

  1. DESCRIPTION:单行描述,说明该管道"每小时把 sales hour 数据导出到 sales_hour_copy 数据源"。描述应能让人不看 SQL 就明白管道的用途与调度节奏。
  2. NODE daily_sales:节点声明。注意 pipe-files.md 的通用约束——管道名必须唯一,节点名必须与管道名及任何资源名不同,且属性名(DESCRIPTION、NODE、SQL、TYPE 等)不允许缩进。
  3. SQL > 后的 %SQL > 开启多行 SQL 块,块首的 % 是多行标记。SQL 主体是一个典型的日粒度聚合:按天(toStartOfDay(starting_date))和国家对 sales 求和,并用 WHERE 限定窗口为"昨天到今天"。
  4. 模板参数 {{ String(country, 'US') }}:这是 Tinybird 的参数化查询语法——country 是一个 String 类型参数,默认值 'US'。该规则要求参数化而不是把值硬编码进 SQL,具体参数处理规则由同 skill 的 rules/sql.md 约定(SKILL.md 中概括为 "SQL is SELECT-only with Tinybird templating rules and strict parameter handling")。
  5. TYPE COPY:将本文件声明为复制型管道,而不是 endpoint 或物化视图。
  6. TARGET_DATASOURCE sales_hour_copy:复制目标数据源。执行时管道会把 SQL 结果写入该数据源。
  7. COPY_SCHEDULE 0 * * * *:cron 表达式,每小时第 0 分钟执行。对照 sink-files.md 中 sink 管道的 EXPORT_SCHEDULE "*/5 * * * *"(每 5 分钟)可以看出两者都采用标准 5 段 cron 语法,只是键名不同。
  8. COPY_MODE append:显式声明追加模式。按照规则第二条的意图,这里是演示"即便等于默认值也建议写明"的最佳实践。

一个值得注意的细节:规则要求"除非明确请求,否则不要包含 COPY_SCHEDULE",而示例中却带有该键。从规则文件的组织方式看,示例承担的是完整语法演示的职责(展示每个键的书写格式),并不等于推荐在创建文件时默认加上调度;实际建文件时应遵循"默认不带 COPY_SCHEDULE"的克制原则。

四、对照仓库中的真实管道文件:materialized 与 sink 的写法差异

理解 COPY 型管道最快的方式是和仓库里真实存在的管道做对比。Ghost 当前的 ghost/core/core/server/data/tinybird/pipes/ 目录下全是 materialized 与 endpoint 两类管道,例如 mv_hits.pipe

NODE mv_hits_1
SQL >
    SELECT
        site_uuid,
        timestamp,
        ...
    FROM mv_hits_0

TYPE MATERIALIZED
DATASOURCE _mv_hits

其末尾(mv_hits.pipe#L185-L186)的 TYPE MATERIALIZED + DATASOURCE _mv_hits 与 copy 管道的 TYPE COPY + TARGET_DATASOURCE 形成直接对照:物化管道用状态修饰符(sumStateuniqExactState)做增量物化,落地到 AggregatingMergeTree 引擎的目标表;而复制管道做的是"按周期把 SQL 结果搬运到另一个数据源"。materialized-files.md 还要求物化目标表的维度按基数从低到高放入 ENGINE_SORTING_KEY、聚合列使用 AggregateFunction 类型——这些键在 copy 管道中完全用不到,两类管道的文件骨架因此差异明显。

mv_daily_pages.pipe 则展示了物化管道中状态修饰符的实战用法:uniqExactState(session_id) as visits, countState() as hits,配合 GROUP BY 把原始 hit 明细预聚合成日粒度行,注释里写明目的是"reducing query scans from millions of raw hits to thousands of daily rows"。这类"预聚合降低扫描量"的思路,与 copy 示例中"每小时只复制昨日聚合结果"的轻量导出定位是同一设计哲学的两个侧面。

sink-files.md 定义的 sink 管道则是第三种形态:它同样"默认不创建"、要求放在 /sinks 目录,但导出方向是外部系统(Kafka、S3、GCS),键名体系也完全不同(EXPORT_CONNECTION_NAMEEXPORT_BUCKET_URIEXPORT_FORMATEXPORT_COMPRESSIONEXPORT_STRATEGY 等),并且同样遵循"不主动包含调度键"的原则(其对应项是 EXPORT_SCHEDULE)。三者对照可以归纳为:

维度 materialized copy sink
用途 增量物化落地本仓数据源 定时复制 SQL 结果到另一数据源 定期导出到 Kafka/S3/GCS 等外部系统
目录约定 /materializations /copies /sinks
类型键 TYPE MATERIALIZED TYPE COPY TYPE SINK
目标键 DATASOURCE TARGET_DATASOURCE EXPORT_CONNECTION_NAME 等一组 EXPORT_* 键
调度键 COPY_SCHEDULE(默认不写) EXPORT_SCHEDULE(默认不写)
特殊约束 状态修饰符 + AggregatingMergeTree 目标表 COPY_MODE append/replace 依赖 connection,尽量复用已有 connection

五、在 Ghost 仓库中定位 Copy Pipe:现状与适用场景

在当前仓库中检索 TYPE COPYCOPY_MODETARGET_DATASOURCE 均无命中:35 个 .pipe 文件全部是 endpoint 或 materialized 类型。这与 copy-files.md 的第一条规则"默认不创建,除非被请求"是自洽的——Copy Pipe 在 Ghost 中属于预留能力,而非默认数据链路的一部分。从规则文件与真实管道的对应关系可以推断,它的典型适用场景是:

  • 需要把某个聚合口径(如按天/小时的汇总)周期性搬运到另一个数据源,供下游报表或其他管道消费;
  • 目标数据源需要在"全量刷新"与"追加"两种写入语义之间选择,此时通过 COPY_MODE replaceCOPY_MODE append 显式声明;
  • 希望管道保持参数化(如示例中的 {{ String(country, 'US') }}),以便同一管道服务不同站点或区域。

六、编写 Copy Pipe 文件的自检清单

综合 copy-files.md 及其引用的通用规则,新建一个 copy 管道文件前可对照检查:

  1. 是否确实被请求创建?未被明确请求时不创建;
  2. 文件是否放在 /copies 目录下,且管道名全局唯一、节点名不与管道名/资源名冲突?
  3. 属性名(DESCRIPTION、NODE、SQL、TYPE、TARGET_DATASOURCE 等)是否均无缩进?
  4. 是否声明了 TYPE COPYTARGET_DATASOURCE
  5. 是否显式写出了 COPY_MODE appendCOPY_MODE replace,而不是依赖默认值?
  6. 是否仅在明确需要时才写入 COPY_SCHEDULE(5 段 cron)?
  7. SQL 是否遵守 Tinybird 模板与参数规则(SELECT-only、参数化取值),复杂聚合是否遵循 SKILL.md Quick Reference 中"filter early, select only needed columns, push complex work later"的原则?

以上各条均可在 .agents/skills/tinybird/ 的规则文件组中逐条找到出处,配合 ghost/core/core/server/data/tinybird/ 下真实的 materialized/endpoint 管道作为参照,即可写出与 Ghost 仓库风格一致的 Copy Pipe 文件。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
594
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
916
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
516
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388