关于 magic-etl-cli
magic-etl-cli 是通过 community-domo-cli 定义和操作 Domo Magic ETL 数据流的技能。它说明 JSON DAG 结构、支持的操作类型、画布组织方式,以及创建、更新、运行和检查数据流的命令。
主要功能
- 01通过 CLI 创建和更新数据流
- 02以 JSON DAG 描述数据流
- 03说明操作类型及依赖关系
- 04用分区和磁贴组织画布
- 05运行数据流并查看执行记录
适用场景
- 01根据数据集构建 Magic ETL 数据流
- 02修改现有数据流定义
- 03运行数据流并检查执行状态
- 04在画布上整理分支与处理阶段
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ stahura/ domo-ai-vibe-rules --skill magic-etl-cli安装后在 Claude Code 中输入/magic-etl-cli确认已加载。
详细介绍
在 Domo 中以编程方式创建 Magic ETL 数据流
概述
Domo 中的 Magic ETL 数据流可完全通过 community-domo-cli 创建、更新和执行。数据流以 JSON 文档定义,其中描述了由操作构成的有向无环图(DAG)——输入节点、转换和输出节点。
所有数据流操作都使用 community-domo-cli。
| 操作 | CLI 命令 |
|---|---|
| 列出数据流 | community-domo-cli dataflows list |
| 获取完整数据流定义 | community-domo-cli dataflows get-definition <ID> |
| 运行数据流 | community-domo-cli -y dataflows run <ID> |
| 检查执行状态 | community-domo-cli dataflows executions <ID> --limit 1 |
| 创建数据流 | community-domo-cli -y dataflows create --body-file <FILE> |
| 更新数据流 | community-domo-cli -y dataflows update <ID> --body-file <FILE> |
| 重命名/启用 | community-domo-cli -y dataflows update <ID> --body-file <FILE> |
重要: 所有操作都使用 community-domo-cli,它会自动处理身份验证。创建的数据流不处于 DRAFT 状态,可立即执行——无需在 UI 中保存。
变更命令需要
-y(或--yes)。 创建、更新和运行操作会提示Execute mutating action? [y/N]。如果 stdin 不是 TTY(脚本、Pythonsubprocess、CI),未指定-y时 CLI 会中止。自动化操作时始终传入-y。
绝不要搜索用户 ID。
responsibleUserId是可选字段——完全省略即可。创建数据流时,绝不要调用community-domo-cli users list或任何用户端点来查找用户 ID。
用于数据流的 CLI 命令
列出所有 Magic ETL 数据流
community-domo-cli dataflows list
获取数据流定义
community-domo-cli dataflows get-definition <DATAFLOW_ID>
通过 GET /dataprocessing/v1/dataflows/{id} 返回完整的 JSON 定义,包括所有操作、输入、输出和 GUI 位置。这是了解 JSON 结构的最佳方式——获取一个现有数据流并研究其定义。执行更新前务必先使用此命令。
运行数据流
community-domo-cli -y dataflows run <DATAFLOW_ID>
列出数据流执行记录
community-domo-cli dataflows executions <DATAFLOW_ID> --limit <LIMIT>
检查特定执行记录
community-domo-cli dataflows execution-get <DATAFLOW_ID> <EXECUTION_ID>
返回执行状态(SUCCESS、FAILED_DATA_FLOW、CREATED、RUNNING)、行数、错误等信息。
通过 CLI 创建数据流
创建
community-domo-cli -y dataflows create --body-file <FILE>
请求正文必须包含 "databaseType": "MAGIC"。创建的数据流可立即执行——详情请参阅注意事项 #7 和 #11。
更新现有数据流
community-domo-cli -y dataflows update <DATAFLOW_ID> --body-file <FILE>
务必先使用 get-definition 获取完整定义,修改后再通过 --body-file 传入。请包含完整定义——PUT 会替换整个数据流。
数据流 JSON 结构
顶层字段
{
"name": "My Magic ETL",
"databaseType": "MAGIC",
"responsibleUserId": 149955692,
"draft": false,
"enabled": true,
"runState": "ENABLED",
"engineProperties": {
"kettle.mode": "STRICT"
},
"inputs": [ ... ],
"outputs": [ ... ],
"actions": [ ... ]
}
| 字段 | 说明 |
|---|---|
name | 数据流的显示名称 |
databaseType | Magic ETL 必须为 "MAGIC" |
responsibleUserId | 所有者的数字用户 ID |
draft | 已发布的数据流设为 false |
enabled | 设为 true 以允许执行 |
runState | 设为 "ENABLED" 以允许计划运行 |
engineProperties | 标准值为 {"kettle.mode": "STRICT"} |
inputs | 输入数据集引用数组 |
outputs | 输出数据集引用数组 |
actions | 操作节点数组(DAG) |
绝不要搜索用户 ID。
responsibleUserId是可选字段——完全省略即可。创建数据流时,绝不要调用community-domo-cli users list或任何用户端点来查找用户 ID。
顶层 gui 字段(画布布局和分区)
gui 字段控制可视化画布布局,包括用于归类相关图块的彩色分区区域。当 useGraphUI: true 时,画布的 elements 数组会控制图块位置(覆盖操作级别的 gui.x/gui.y)。
{
"gui": {
"version": "1.0",
"canvases": {
"default": {
"canvasSettings": {
"coarserGrid": false,
"hideCoarserGridPopUp": false,
"backgroundVariant": "None"
},
"elements": [
{ "type": "Section", ... },
{ "type": "Tile", ... }
],
"disabledActions": []
}
},
"useGraphUI": true
}
}
Section 元素(彩色区域背景)
Section 是彩色矩形区域,可在画布上直观地将相关 Tile 分组:
{
"id": "a-unique-uuid",
"type": "Section",
"x": 56,
"y": 72,
"width": 1320,
"height": 288,
"name": "Work Orders Denormalization",
"backgroundColor": "var(--colorChartBlue6)"
}
| 字段 | 说明 |
|---|---|
id | Section 的唯一 UUID |
type | 必须为 "Section" |
x、y | 在画布上的绝对位置(左上角) |
width、height | 彩色区域的尺寸,单位为像素 |
name | 显示在 Section 标题中的标签 |
backgroundColor | 区域颜色的 CSS 变量(见下表) |
可用的 Section 背景颜色
| CSS 变量 | 颜色 | 建议用途 |
|---|---|---|
var(--colorChartBlue6) | 浅蓝色 | 输入/暂存流水线 |
var(--colorChartGreen6) | 浅绿色 | 质量/验证流水线 |
var(--colorChartPurple6) | 浅紫色 | 输出/发布流水线 |
var(--colorChartOrange6) | 浅橙色 | 转换/丰富流水线 |
var(--colorChartRed6) | 浅红色 | 筛选/排除流水线 |
var(--colorChartYellow6) | 浅黄色 | 共享/维度表 |
后缀 6 表示最浅的色调——非常适合作为 Section 背景,这样 Tile 标签仍然清晰可读。
Tile 元素(操作位置)
每个操作节点在画布中都有对应的 Tile 元素。Tile 可以设为父级,放置在 Section 内;此时,它们的 x/y 是相对于 Section 位置的坐标:
{
"id": "LoadFromVault-work_orders",
"type": "Tile",
"x": 72,
"y": 56,
"parentId": "section-uuid-here",
"color": null,
"colorSource": null
}
| 字段 | 说明 |
|---|---|
id | 必须与操作的 id 字段一致 |
type | 必须为 "Tile" |
x、y | 位置——无 parentId 时为绝对坐标;设置 parentId 时为相对于父级 Section 的坐标 |
parentId | 父级 Section 元素的 UUID(未设置父级的 Tile 可省略) |
color | Tile 图标的可选整数颜色代码 |
重新设置父级的公式: 将 Tile 移入 Section 时,将绝对坐标转换为相对坐标:
relativeX = absoluteX - section.xrelativeY = absoluteY - section.y
没有 parentId 的 Tile 会按画布绝对坐标渲染,并浮置在所有 Section 之外。
创建数据流时务必添加 Section
使用多个逻辑分支或处理阶段构建数据流时,务必添加 Section 元素来组织视觉布局。这是最佳实践,可让数据流一目了然。请按以下方式对 Tile 分组:
- 流水线分支(例如,每个事实表的连接链都使用单独的 Section)
- 处理阶段(例如,“输入/暂存”、“转换”、“输出”)
- 共享资源(例如,多个分支共用的维度表)
为每个 Section 指定不同的颜色,以便在视觉上加以区分。
Inputs 数组
每个输入都引用一个馈入数据流的 Domo 数据集:
"inputs": [
{
"dataSourceId": "422efbf4-6c96-4576-907b-eacae8379d5d",
"executeFlowWhenUpdated": false,
"dataSourceName": "RAW | SFDC | Accounts",
"onlyLoadNewVersions": false,
"recentVersionCutoffMs": 0
}
]
| 字段 | 说明 |
|---|---|
dataSourceId | 输入数据集的 UUID |
dataSourceName | 显示名称(便于阅读) |
executeFlowWhenUpdated | 设为 true 时,在此输入更新时自动触发数据流 |
onlyLoadNewVersions | 设为 true 时,仅处理新版本的数据 |
Outputs 数组
对于输出数据集尚不存在的新数据流:
"outputs": [
{
"dataSourceId": null,
"dataSourceName": "SFDC | Account Summary",
"versionChainType": "REPLACE"
}
]
将 dataSourceId 设为 null,表示让 Domo 在首次运行时创建新数据集。首次成功运行后,Domo 会分配一个 UUID。
对于已有的输出数据集:
"outputs": [
{
"dataSourceId": "8fe448eb-231d-4ff5-95f1-86db64336e96",
"dataSourceName": "SFDC | Account Opportunity Summary",
"versionChainType": "REPLACE"
}
]
versionChainType:"REPLACE" 表示每次运行都会替换所有数据。其他选项包括 "APPEND"。
操作类型
操作是 DAG 中的节点。每个操作都有唯一的 id、一个 type,并通过 dependsOn 引用其上游依赖项。
有效类型:LoadFromVault、PublishToVault、MergeJoin、GroupBy、WindowAction、Filter、ExpressionEvaluator、SQL
无效类型(会导致 DP-0069):SaveToVault、SelectValues、RenameColumns
常见操作字段
每个操作都包含以下字段:
{
"type": "ActionType",
"id": "unique-action-id",
"name": "Human-readable name",
"dependsOn": ["upstream-action-id-1", "upstream-action-id-2"],
"settings": {
"preferredDatabaseEntityType": "TEMP_VIEW"
},
"gui": {
"x": 128,
"y": 128,
"color": null,
"colorSource": null,
"sampleJson": null
},
"tables": [{}]
}
| 字段 | 描述 |
|---|---|
id | 此操作节点的唯一标识符。可以是任意字符串,但通常使用 TypeName-uuid |
dependsOn | 此操作运行前必须完成的操作 ID 数组 |
gui.x / gui.y | 可视化画布中的位置。当 useGraphUI: true 时,顶层的 gui.canvases.default.elements 数组优先级更高 — 请同时设置这两个字段以保持一致 |
settings.preferredDatabaseEntityType | 始终为 "TEMP_VIEW" |
tables | 始终为 [{}] |
LoadFromVault(输入节点)
将 Domo 数据集中的数据加载到数据流中。
{
"type": "LoadFromVault",
"id": "LoadFromVault-accounts",
"name": "RAW | SFDC | Accounts",
"settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
"gui": {"x": 128, "y": 128, "color": null, "colorSource": null, "sampleJson": null},
"previewRowLimit": 10000,
"propagateAi": false,
"filterPolicy": "LEGACY",
"dataSourceId": "422efbf4-6c96-4576-907b-eacae8379d5d",
"sourceType": "AUTO",
"executeFlowWhenUpdated": false,
"pseudoDataSource": false,
"truncateTextColumns": false,
"truncateRows": false,
"onlyLoadNewVersions": false,
"recentVersionCutoffMs": 0,
"tables": [{}]
}
关键字段:
dataSourceId:要加载的数据集的 UUIDname:应与数据集名称一致,以便清晰识别- 无
dependsOn— 这是一个根节点
MergeJoin(联接)
根据指定的键联接两个上游操作。
{
"type": "MergeJoin",
"id": "MergeJoin-accounts-opps",
"name": "Join Accounts & Opp Summary",
"dependsOn": ["LoadFromVault-accounts", "GroupBy-opp-summary"],
"disabled": false,
"removeByDefault": false,
"notes": [],
"settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
"gui": {"x": 576, "y": 320, "color": null, "colorSource": null, "sampleJson": null},
"previewRowLimit": null,
"joinType": "LEFT OUTER",
"relationshipType": "MTM",
"step1": "LoadFromVault-accounts",
"step2": "GroupBy-opp-summary",
"keys1": ["Id"],
"keys2": ["AccountId"],
"on": null,
"schemaModification1": [],
"schemaModification2": [
{"name": "AccountId", "rename": "Opp_AccountId", "remove": true}
]
}
| 字段 | 描述 |
|---|---|
joinType | "LEFT OUTER"、"INNER"、"RIGHT OUTER"、"FULL OUTER" |
relationshipType | "MTM" — 使用此缩写,而不是 "MANY_TO_MANY"(会导致验证错误) |
step1 | 联接左侧的操作 ID |
step2 | 联接右侧的操作 ID |
keys1 | 用于联接的 step1 列名数组 |
keys2 | 用于联接的 step2 列名数组(按位置与 keys1 匹配) |
schemaModification1 | 重命名或移除 step1(左侧)的列 |
schemaModification2 | 重命名或移除 step2(右侧)的列,以避免名称冲突 |
dependsOn | 必须包含 step1 和 step2 操作 ID |
**注意:**键可以不对称 — keys1: ["fldWorkCodeID"] / keys2: ["ID"]。Domo 按数组位置匹配,而不是按列名匹配。
schemaModification1 / schemaModification2
当两个数据集包含同名列(例如,两者都有 Id、Name、Description)时,使用 schemaModification2 重命名或移除右侧(step2)数据集中的冲突列:
"schemaModification2": [
{"name": "Description", "rename": "Opportunities.Description", "remove": false},
{"name": "Id", "rename": "Opportunities.Id", "remove": false},
{"name": "Name", "rename": "Opportunities.Name", "remove": false},
{"name": "AccountId", "rename": "Opp_AccountId", "remove": true}
]
remove: true— 从输出中完全移除该列remove: false— 保留该列,但将其重命名为rename的值
GroupBy(聚合)
通过对列分组并应用聚合函数来汇总数据。
{
"type": "GroupBy",
"id": "GroupBy-opp-summary",
"name": "Summarize Opportunities per Account",
"dependsOn": ["LoadFromVault-opportunities"],
"settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
"gui": {"x": 352, "y": 512, "color": null, "colorSource": null, "sampleJson": null},
"input": "LoadFromVault-opportunities",
"addLineNumber": false,
"giveBackRow": false,
"allRows": false,
"groups": [
{"name": "AccountId"}
],
"fields": [
{"name": "Opportunity Count", "source": "Id", "type": "COUNT_ALL", "valuefield": null, "expression": null, "settings": null},
{"name": "Total Amount", "source": "Amount", "type": "SUM", "valuefield": null, "expression": null, "settings": null},
{"name": "Avg Amount", "source": "Amount", "type": "AVERAGE", "valuefield": null, "expression": null, "settings": null},
{"name": "Total Expected Revenue", "source": "ExpectedRevenue", "type": "SUM", "valuefield": null, "expression": null, "settings": null},
{"name": "Avg Probability", "source": "Probability", "type": "AVERAGE", "valuefield": null, "expression": null, "settings": null}
],
"tables": [{}]
}
| 字段 | 描述 |
|---|---|
input | 上游数据的操作 ID |
groups | 用于分组的列数组。每个条目:{"name": "ColumnName"} |
fields | 聚合定义数组 |
聚合字段定义
{
"name": "Total Amount",
"source": "Amount",
"type": "SUM",
"valuefield": null,
"expression": null,
"settings": null
}
| 字段 | 描述 |
|---|---|
name | 聚合值的输出列名 |
source | 要聚合的源列名 |
type | 聚合函数(见下文) |
聚合类型
| 类型 | 描述 | 已确认 |
|---|---|---|
SUM | 值的总和 | 是 |
AVERAGE | 值的平均值 | 是 |
COUNT_ALL | 所有行的计数(包括 null) | 是 |
COUNT_DISTINCT | 不同值的计数 | |
MIN | 最小值 | 是 |
MAX | 最大值 | |
FIRST | 分组中的第一个值 | |
LAST | 分组中的最后一个值 | |
CONCAT_COMMA | 使用逗号分隔符拼接值 |
**重要:**API 使用 MIN 和 MAX,而不是 MINIMUM 或 MAXIMUM。使用 MINIMUM 会返回验证错误:"The value is invalid for expected type... AggregateType"。这是通过测试发现的。
基于表达式的聚合(高级)
除了使用 source + type,你还可以使用完整的 SQL 聚合表达式。将 source、type 和 valuefield 设为 null,并将完整表达式放在 expression 中:
{
"name": "Total Hours",
"source": null,
"type": null,
"valuefield": null,
"expression": "SUM(IFNULL(`Hours`,0))",
"settings": null
}
关键:expression 必须是完整的 SQL 聚合表达式 — 不能只是函数名。
"expression": "SUM(IFNULL(\Hours`,0))"且"source": null` — 正确"expression": "SUM"且"valuefield": "Hours"— 错误(会将 "SUM" 视为列名)
这样便可以直接在 GroupBy 中嵌入 CASE WHEN 等复杂逻辑,而无需预先使用 GroupBy ExpressionEvaluator:
{
"name": "LTM_Revenue",
"source": null, "type": null, "valuefield": null,
"expression": "SUM(CASE WHEN `Date` >= DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 12 MONTH) THEN IFNULL(`Revenue`,0) ELSE 0 END)",
"settings": null
}
窗口操作(排名与窗口)
应用窗口函数——排名、行编号、偏移(lag/lead)——按分组列划分,并按排序列排序。这是 Magic ETL UI 中“Rank & Window”磁贴的编程等效形式。
{
"type": "WindowAction",
"id": "WindowAction-first-order",
"name": "First Order Date per Customer",
"dependsOn": ["LoadFromVault-finance"],
"settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
"gui": {"x": 352, "y": 128, "color": null, "colorSource": null, "sampleJson": null},
"input": "LoadFromVault-finance",
"groupRules": [
{"column": "customer", "caseSensitive": false}
],
"orderRules": [
{"column": "date_ymd", "caseSensitive": false, "ascending": true}
],
"additions": [
{
"name": "Customer Order Rank",
"operation": {
"type": "RANKING",
"operationType": "ROW_NUMBER",
"column": null,
"defaultValue": null,
"amount": null
}
}
],
"tables": [{}]
}
| 字段 | 说明 |
|---|---|
input | 上游数据的操作 ID |
groupRules | 分区列——窗口函数在每个分组内应用 |
orderRules | 每个分区内的排序顺序 |
additions | 要作为新列添加的窗口函数定义数组 |
groupRules
定义 PARTITION BY 列:
"groupRules": [
{"column": "customer", "caseSensitive": false},
{"column": "region", "caseSensitive": false}
]
每个条目都会按该列对数据进行分区。多个条目会创建复合分区键。
orderRules
定义每个分区内的 ORDER BY:
"orderRules": [
{"column": "date_ymd", "caseSensitive": false, "ascending": true}
]
| 字段 | 说明 |
|---|---|
column | 用于排序的列 |
caseSensitive | 字符串排序是否区分大小写 |
ascending | true 表示升序,false 表示降序 |
多个 orderRules 会创建复合排序键。
additions(窗口函数定义)
每个 addition 都会创建一个新列,其中包含窗口函数的结果:
{
"name": "Output Column Name",
"operation": {
"type": "RANKING",
"operationType": "ROW_NUMBER",
"column": null,
"defaultValue": null,
"amount": null
}
}
窗口操作类型
排名操作(type: "RANKING"):
| operationType | 说明 | column | amount |
|---|---|---|---|
ROW_NUMBER | 分区内的顺序编号(1、2、3……) | null | null |
RANK | 并列时排名会跳号(1、2、2、4……) | null | null |
DENSE_RANK | 并列时排名不跳号(1、2、2、3……) | null | null |
偏移操作(type: "OFFSET"):
| operationType | 说明 | column | amount |
|---|---|---|---|
LAG | 分区内前 N 行的值 | 源列名称 | 要向前回溯的行数 |
LEAD | 分区内后 N 行的值 | 源列名称 | 要向后查看的行数 |
示例——使用 LAG 获取前一天的收入:
{
"name": "Previous Day Revenue",
"operation": {
"type": "OFFSET",
"operationType": "LAG",
"column": "revenue",
"defaultValue": null,
"amount": 1
}
}
示例——使用 ROW_NUMBER 对每位客户的订单排名:
{
"name": "Customer Order Rank",
"operation": {
"type": "RANKING",
"operationType": "ROW_NUMBER",
"column": null,
"defaultValue": null,
"amount": null
}
}
将 WindowAction 与 GroupBy 结合使用
一种常见模式是使用 WindowAction 进行行级排名,然后使用 GroupBy 进行聚合。例如,要查找每位客户的首个订单日期:
- WindowAction:按
customer分区,按date_ymd升序排序,添加ROW_NUMBER - GroupBy:按
customer分组,对date_ymd使用MIN以获取首个订单日期,并对数值列使用SUM/AVERAGE
WindowAction 会传递所有原始列以及新增列,因此下游操作可以访问所有数据。
过滤器(行筛选)
根据列条件筛选行。这是 Magic ETL UI 中“Filter Rows”磁贴的编程等效形式。
{
"type": "Filter",
"id": "Filter-exclude-florida",
"name": "Exclude Florida",
"dependsOn": ["LoadFromVault-sales"],
"settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
"gui": {"x": 352, "y": 256, "color": null, "colorSource": null, "sampleJson": null},
"input": "LoadFromVault-sales",
"filterList": [
{
"leftField": "state",
"rightField": null,
"rightValue": {"value": "Florida", "type": "STRING"},
"rightExpr": "'Florida'",
"operator": "NE",
"expression": null,
"andFilterList": []
}
],
"tables": [{}]
}
| 字段 | 说明 |
|---|---|
input | 上游数据的操作 ID |
filterList | 筛选条件数组(按 OR 逻辑组合) |
andFilterList | 筛选器中用于 AND 逻辑的嵌套数组 |
筛选条件字段
| 字段 | 说明 |
|---|---|
leftField | 要筛选的列名称 |
operator | 比较运算符(见下表) |
rightValue | 类型化值对象:{"value": "Florida", "type": "STRING"} |
rightExpr | 值的字符串表达式;字符串需用单引号括起来:"'Florida'" |
rightField | 要比较的列名称(用于列与列的比较,否则为 null) |
重要: 对于字符串比较,rightValue 必须是包含 value 和 type 字段的类型化对象,且 rightExpr 必须用单引号括起该值。为 rightValue 使用普通字符串会返回 VALIDATION-DE 错误。
基于表达式的筛选(替代方式)
除了使用 leftField/operator/rightValue,也可以使用原始 SQL expression 来处理复杂条件:
{
"leftField": null,
"rightField": null,
"rightValue": null,
"rightExpr": null,
"operator": null,
"expression": "IFNULL(TRIM(`column_name`),'') <> ''",
"andFilterList": []
}
这适用于多条件筛选或包含函数调用的筛选。该表达式是 SQL WHERE 子句片段。
筛选运算符
| 运算符 | 描述 | 已确认 |
|---|---|---|
NE | 不等于 | 是 |
EQ | 等于 | |
LT | 小于 | |
GT | 大于 | |
LE | 小于或等于 | |
GE | 大于或等于 | |
NN | 不为 null | 是(来自现有数据流) |
NL | 为 null | |
NIN | 不在列表中 | |
IN | 在列表中 |
rightValue 类型值
| 类型 | 用途 |
|---|---|
STRING | 文本比较 |
NUMERIC | 数字比较 |
DATE | 日期比较 |
ExpressionEvaluator(添加公式)
使用 Domo 的表达式语言添加计算列。这是 Magic ETL UI 中“添加公式”磁贴的编程等效方式。
{
"type": "ExpressionEvaluator",
"id": "ExpressionEvaluator-month-trunc",
"name": "Add Month Column",
"dependsOn": ["Filter-exclude-florida"],
"settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
"gui": {"x": 480, "y": 256, "color": null, "colorSource": null, "sampleJson": null},
"input": "Filter-exclude-florida",
"expressions": [
{
"expression": "concat(year(`date_ymd`),MONTHNAME(`date_ymd`))",
"fieldName": "Year_Month",
"settings": {}
}
],
"tables": [{}]
}
| 字段 | 描述 |
|---|---|
input | 上游数据的操作 ID |
expressions | 公式定义数组 |
表达式定义
{
"expression": "concat(year(`date_ymd`),MONTHNAME(`date_ymd`))",
"fieldName": "Year_Month",
"settings": {}
}
| 字段 | 描述 |
|---|---|
expression | Domo 公式表达式。列名必须用反引号括起来。 |
fieldName | 新输出列的名称 |
settings | 空对象 {} |
已知可用函数
| 函数 | 描述 | 示例 |
|---|---|---|
year() | 从日期中提取年份 | year(\date_ymd`)` |
MONTH() | 提取月份数字(1-12) | MONTH(\date_ymd`)` |
MONTHNAME() | 从日期中提取月份名称 | MONTHNAME(\date_ymd`)` |
concat() | 拼接字符串 | concat(year(\date_ymd`), MONTHNAME(`date_ymd`))` |
DATE() | 转换为日期类型 | DATE(\date_ymd`)` |
DATE_FORMAT() | 将日期格式化为字符串 | DATE_FORMAT(\date_ymd`, 'yyyy-MM-dd')` |
LEFT() | 左侧子字符串 | LEFT(\Date`, 7)`,从 "2025-01-15" 中提取年月 |
LPAD() | 在字符串左侧填充 | LPAD(MONTH(\date`), 2, '0')` |
IFNULL() | null 替换(仅 2 个参数) | IFNULL(\col`, 0)` |
COALESCE() | null 替换(多个参数) | COALESCE(\a`, `b`, 'default')` |
TRIM() | 移除空白字符 | TRIM(\col`)` |
CAST() | 类型转换 | CAST(NULL AS DATETIME) |
LAST_DAY() | 月末日期 | LAST_DAY(\date`)` |
DATE_SUB() | 减去时间间隔 | DATE_SUB(\date`, INTERVAL 12 MONTH)` |
CONVERT_TZ() | 时区转换 | CONVERT_TZ(CURRENT_TIMESTAMP(),'UTC','US/Eastern') |
CURRENT_TIMESTAMP() | 当前日期时间 | CURRENT_TIMESTAMP() |
重要: TRUNC_MONTH() 不是有效函数,会返回 "Unknown function: TRUNC_MONTH"。若要将日期截断到月份级别,请使用 concat(year(...), MONTHNAME(...)) 或类似的基于字符串的方法。
表达式行为规则
- 表达式会按顺序处理——后面的表达式可以引用同一磁贴中前面表达式计算出的字段
- 添加与现有列具有相同
fieldName的表达式时,会替换该列的值(适用于类型转换或重新格式化) IFNULL()恰好接受 2 个参数;多参数 null 处理请使用COALESCE(a, b, c)CAST(NULL AS DATETIME)可用于创建类型为日期时间的 null 列
在单个 ExpressionEvaluator 操作中可以添加多个表达式——每个表达式都会创建一个新列(或替换现有列)。所有原始列都会保留并传递到后续步骤。
Unique(去重)
根据指定的键列移除重复行。这是“移除重复项”磁贴的编程等效方式。
{
"type": "Unique",
"id": "Unique-dedup",
"name": "Deduplicate",
"dependsOn": ["SelectValues-final"],
"settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
"gui": {"x": 800, "y": 256, "color": null, "colorSource": null, "sampleJson": null},
"input": "SelectValues-final",
"countRows": false,
"fields": [
{"name": "ColA", "caseInsensitive": false},
{"name": "ColB", "caseInsensitive": false}
],
"tables": [{}]
}
| 字段 | 描述 |
|---|---|
input | 上游数据的操作 ID |
countRows | 设为 true 时,会添加一列,显示找到的重复项数量 |
fields | 定义唯一性的列数组。根据所列所有列的值去重 |
fields[].caseInsensitive | 设为 true 时,字符串匹配不区分大小写 |
提示: 对可能导致行数膨胀的联接(例如,多对多联接)之后添加 Unique 磁贴。
SelectValues(旧版 / 不适用于新流程)
选择特定列,并可选择为其重命名。
{
"type": "SelectValues",
"id": "SelectValues-final",
"name": "Select Final Columns",
"dependsOn": ["MergeJoin-final"],
"settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
"gui": {"x": 1024, "y": 320, "color": null, "colorSource": null, "sampleJson": null},
"input": "MergeJoin-final",
"select": [
{"name": "Id", "rename": "Account ID"},
{"name": "Name", "rename": "Account Name"},
{"name": "Industry"},
{"name": "Contact Count"},
{"name": "Total Amount"}
],
"tables": [{}]
}
- 只有
select中列出的列会被保留;其他列都会被删除 - 省略
rename可保留原列名
替代格式 — 使用 fields 而不是 select。只列出要保留的列(可选择重命名)。未列出的列都会被删除。不要添加 remove: true 条目 — 这会导致 DP-0003 验证错误。
只列出要保留的列(可选择重命名)。未列出的列都会被删除。不要添加 remove: true 条目 — 这会导致 DP-0003 验证错误。
"fields": [
{"name": "ID", "rename": "Dataflow ID"},
{"name": "Display Name", "rename": "Dataflow Name"},
{"name": "Link", "rename": "Dataflow Link"}
]
最简字段条目只需 {"name": "...", "rename": "..."}。不要包含 type、dateFormat、settings 或 remove — 使用 fields 格式时,这些会导致 DP-0003 Action is improperly configured 错误。
PublishToVault(输出节点)
将最终数据写入 Domo 数据集。
{
"type": "PublishToVault",
"id": "PublishToVault-my-output",
"name": "Output Dataset Name",
"dependsOn": ["last-action-id"],
"settings": {"preferredDatabaseEntityType": "DYNAMIC_TABLE"},
"inputs": ["last-action-id"],
"dataSource": {
"guid": null,
"type": "DataFlow",
"name": "Output Dataset Name",
"description": "",
"cloudId": null
},
"versionChainType": "REPLACE",
"schemaSource": "DATAFLOW",
"partitioned": false,
"tables": [{}]
}
| 字段 | 说明 |
|---|---|
dependsOn | 包含最终转换操作 ID 的数组 |
inputs | 必须包含相同的最终转换操作 ID |
dataSource.type | "DataFlow" |
dataSource.name | 输出数据集的名称 |
dataSource.guid | 新输出为 null;现有输出数据集为现有 UUID |
dataSource.cloudId | 对于标准的 dataflow 管理型输出,为 null |
versionChainType | "REPLACE"(完全替换)或 "APPEND" |
schemaSource | "DATAFLOW" |
partitioned | false |
tables | [{}] |
对于新建的数据流,请完全省略 guid。首次成功运行时,Domo 会分配真实的输出数据集 UUID。
完整示例:账户摘要 ETL
此示例创建一个数据流,用于:
- 加载 3 个 Salesforce 数据集(账户、联系人、商机)
- 按账户聚合联系人(计数)
- 按账户聚合商机(计数、总金额、平均金额、预期收入、平均概率)
- 将两个聚合结果左连接到账户表
- 输出每个账户一行,并包含所有摘要指标
流水线图
LoadFromVault(Accounts) ─────────────────────┐
├─ MergeJoin(LEFT) ──┐
LoadFromVault(Opportunities) │ on Id=AccountId │
└─ GroupBy(AccountId) ─────────────────────┘ │
COUNT(Id) → Opportunity Count ├─ MergeJoin(LEFT) ─── PublishToVault
SUM(Amount) → Total Amount │ on Id=AccountId
AVG(Amount) → Avg Amount │
SUM(ExpectedRevenue) → Total Expected Revenue │
AVG(Probability) → Avg Probability │
│
LoadFromVault(Contacts) │
└─ GroupBy(AccountId) ──────────────────────────────────────────┘
COUNT(Id) → Contact Count
创建命令
community-domo-cli -y dataflows create --body-file sfdc_account_summary_etl.json
执行
community-domo-cli -y dataflows run <DATAFLOW_ID>
完整示例:使用排名和窗口的客户摘要
此示例创建一个数据流,用于:
- 加载一个财务数据集(329,460 行,包含客户、日期、销售额、收入、销货成本)
- 使用 WindowAction 按日期为每位客户的订单排名(ROW_NUMBER)
- 按客户聚合:首单日期(MIN)、销售额/收入/销货成本的 SUM 和 AVERAGE,以及订单数
流水线图
LoadFromVault(Mododata | Finance) 329,460 rows
└── WindowAction: ROW_NUMBER partitioned by customer, ordered by date_ymd ASC
└── GroupBy(customer):
MIN(date_ymd) → First Order Date
SUM(sales) → Total Sales
AVG(sales) → Avg Sales
SUM(revenue) → Total Revenue
AVG(revenue) → Avg Revenue
SUM(cogs) → Total COGS
AVG(cogs) → Avg COGS
COUNT(date_ymd)→ Order Count
└── PublishToVault → 104 customer rows
关键 JSON 片段
WindowAction(排名和窗口磁贴):
{
"type": "WindowAction",
"id": "WindowAction-first-order",
"name": "First Order Date per Customer",
"dependsOn": ["LoadFromVault-finance"],
"input": "LoadFromVault-finance",
"groupRules": [
{"column": "customer", "caseSensitive": false}
],
"orderRules": [
{"column": "date_ymd", "caseSensitive": false, "ascending": true}
],
"additions": [
{
"name": "Customer Order Rank",
"operation": {
"type": "RANKING",
"operationType": "ROW_NUMBER",
"column": null,
"defaultValue": null,
"amount": null
}
}
]
}
GroupBy:使用 MIN 获取首单日期:
{
"type": "GroupBy",
"id": "GroupBy-customer-summary",
"name": "Customer Aggregations",
"dependsOn": ["WindowAction-first-order"],
"input": "WindowAction-first-order",
"groups": [{"name": "customer"}],
"fields": [
{"name": "First Order Date", "source": "date_ymd", "type": "MIN"},
{"name": "Total Sales", "source": "sales", "type": "SUM"},
{"name": "Avg Sales", "source": "sales", "type": "AVERAGE"},
{"name": "Total Revenue", "source": "revenue", "type": "SUM"},
{"name": "Avg Revenue", "source": "revenue", "type": "AVERAGE"},
{"name": "Total COGS", "source": "cogs", "type": "SUM"},
{"name": "Avg COGS", "source": "cogs", "type": "AVERAGE"},
{"name": "Order Count", "source": "date_ymd", "type": "COUNT_ALL"}
]
}
结果
输出数据集:104 行(每位客户一行),包含以下列:customer、First Order Date、Total Sales、Avg Sales、Total Revenue、Avg Revenue、Total COGS、Avg COGS、Order Count。
完整示例:使用筛选器和公式的月度部门指标
此示例创建一个数据流,用于:
- 加载一个销售数据集(481,643 行)
- 筛除 state = 'Florida' 的行
- 使用
concat(year(), MONTHNAME())添加Year_Month列 - 按 Year_Month + department + metric_name 聚合:对 revenue、store_revenue、web_revenue、mobile_revenue、total_costs、visits 执行 SUM 和 AVERAGE
流水线图
LoadFromVault(Mododata | Sales) 481,643 rows
└── Filter: state != 'Florida'
└── ExpressionEvaluator: Year_Month = concat(year(date_ymd), MONTHNAME(date_ymd))
└── GroupBy(Year_Month, department, metric_name):
SUM/AVG for revenue, store_revenue, web_revenue,
mobile_revenue, total_costs, visits
└── PublishToVault → 14,057 rows
关键 JSON 片段
筛选器(排除特定值):
{
"type": "Filter",
"id": "Filter-exclude-florida",
"name": "Exclude Florida",
"dependsOn": ["LoadFromVault-sales"],
"input": "LoadFromVault-sales",
"filterList": [
{
"leftField": "state",
"rightField": null,
"rightValue": {"value": "Florida", "type": "STRING"},
"rightExpr": "'Florida'",
"operator": "NE",
"expression": null,
"andFilterList": []
}
]
}
ExpressionEvaluator(将日期转换为年月字符串):
{
"type": "ExpressionEvaluator",
"id": "ExpressionEvaluator-month-trunc",
"name": "Add Month Column",
"dependsOn": ["Filter-exclude-florida"],
"input": "Filter-exclude-florida",
"expressions": [
{
"expression": "concat(year(`date_ymd`),MONTHNAME(`date_ymd`))",
"fieldName": "Year_Month",
"settings": {}
}
]
}
结果
输出:14,057 行(每月 × 部门 × 指标名称一行,不包含 Florida)。粒度从 481K 条日度记录降低为 14K 条月度聚合记录。
ETL 错误代码参考
数据流执行失败时,lastExecution.errors[] 中的错误对象会包含 code 字段。请使用下表进行诊断:
| 代码 | 类别 | 含义 | 典型修复方法 |
|---|---|---|---|
DP-DSNF | 缺少输入 | 所需数据集不存在 | 重新创建数据集,或移除 LoadFromVault 瓦片 |
DP-61100 | 缺少输入 | 与 DP-DSNF 相同(备用代码) | 同上 |
DP-0001 | 架构不匹配 | 引用的列不存在 | 上游架构已更改——更新列引用 |
DP-0059 | 公式错误 | 表达式语法错误 | 修正公式(例如 CASE 语句缺少 END) |
DP-0118 | 代码/模型崩溃 | 转换作业失败 | 检查 Python 脚本或 AI 模型瓦片 |
DP-TGTFR | 数据量 | Batch Text Generation 需要至少 100 行 | 确保输入有足够的行 |
MYSQL-601072 | 缺少联接键 | 表中不存在键列 | 更新联接键列名 |
DP-0000 | 未知 | 没有 API 级别的详细信息 | 在 Domo UI 中检查 |
将错误追溯到具体瓦片
错误对象包含一个 parameters 映射,其中有 _actionId(失败瓦片的 UUID)。将其与数据流中的 actions[].id 匹配:
errors = dataflow.get("lastExecution", {}).get("errors", [])
actions_by_id = {a["id"]: a for a in dataflow.get("actions", [])}
for e in errors:
action_id = e.get("parameters", {}).get("_actionId", "")
tile = actions_by_id.get(action_id, {})
print(f'Error: [{e["code"]}] {e["localizedMessage"]}')
print(f'Tile: "{tile.get("name", "?")}" (type: {tile.get("type", "?")})')
print(f'Property: {e.get("parameters", {}).get("_propertyPath", "")}')
_actionId 瓦片类型 | 检查内容 |
|---|---|
ExpressionEvaluator | expressions[].expression — 公式文本 |
LoadFromVault | dataSourceId — 输入数据集 UUID |
MergeJoin | keys1 / keys2 — 联接键列名 |
SelectValues | fields[].name — 要选择的列名 |
Filter | filterList[].leftField — 筛选列 |
PublishToVault | dataSource.guid — 输出数据集 UUID |
常见问题
1. DP-DSCF/DP-0069 失败 — 操作类型错误或 PublishToVault 结构有误
DP-0069 表示使用了非法操作类型(例如 SaveToVault、SelectValues、RenameColumns)。DP-DSCF 表示输出提交失败,通常与格式错误的 PublishToVault 负载有关。
根本原因: 不支持的操作类型,或 PublishToVault 结构不完整/不正确。
修复方法: 使用受支持的操作类型,并采用以下 PublishToVault 结构:
{
"type": "PublishToVault",
"id": "PublishToVault-my-output",
"name": "Output Dataset Name",
"dependsOn": ["last-action-id"],
"settings": {"preferredDatabaseEntityType": "DYNAMIC_TABLE"},
"inputs": ["last-action-id"],
"dataSource": {"guid": null, "type": "DataFlow", "name": "Output Dataset Name", "description": "", "cloudId": null},
"versionChainType": "REPLACE",
"schemaSource": "DATAFLOW",
"partitioned": false,
"tables": [{}]
}
2. SelectValues — 旧版失败模式(请勿使用)
SelectValues 经常导致失败,在此技能中应视为不支持新自动化使用。
建议: 完全省略 SelectValues。将 PublishToVault.dependsOn 直接设置为最终转换节点(通常是 MergeJoin),让该节点的输出架构自然传递。
旧版参考(仅用于诊断):较早的负载使用 fields 来指定仅保留的列(没有 "remove": true,也没有额外的 type / dateFormat / settings)。
"fields": [
{"name": "ID", "rename": "Dataset ID"},
{"name": "Name", "rename": "Dataset Name"}
]
未列出的列会被删除。请勿添加 remove 条目。
3. 联接中的列名冲突
联接两个包含同名列(例如 Id、Name、Description)的数据集时,必须在 MergeJoin 上使用 schemaModification2 重命名或删除右侧数据集中的冲突列。否则,下游会出现列名不明确的问题。
4. 操作 ID 必须唯一
actions 数组中的每个操作都需要唯一的 id 字符串。常见格式为 TypeName-uuid(例如 "LoadFromVault-b71d89d7-6c08-44ad-a503-ebed046377e0"),但任何唯一字符串都可以(例如 "LoadFromVault-accounts")。
5. dependsOn 必须与 step1/step2/input 匹配
对于 MergeJoin,dependsOn 数组必须包含 step1 和 step2 操作 ID。对于 GroupBy,dependsOn 必须包含 input 操作 ID。不匹配会导致数据流失败。
6. GUI 位置会影响可视化画布
gui.x 和 gui.y 的值决定节点在 Domo Magic ETL 可视化编辑器中的显示位置。水平间隔约 224px、垂直间隔约 192px,可使布局更清晰。输入节点通常从 x: 128 开始。
设置 useGraphUI: true(现代画布模式)时,图块位置由顶层的 gui.canvases.default.elements 数组控制,而不是由操作级别的 gui 字段控制。请始终同时设置这两处,以保持一致。完整的 Section 和 Tile 元素架构请参见“顶层 gui 字段”部分。
7. 创建数据流 — 身份验证与执行(2026 年 4 月更新)
身份验证: community-domo-cli 会自动处理身份验证。底层的 POST /dataprocessing/v1/dataflows 调用使用 CLI 配置的会话即可。请求正文必须包含 "databaseType": "MAGIC"。创建的数据流不处于 DRAFT 状态,可以立即执行,无需在 UI 中保存。
输出: 当请求正文包含 "outputs": [{"dataSourceId": null, "dataSourceName": "...", "versionChainType": "REPLACE"}] 时,Domo 会立即分配一个真实的输出数据集 UUID。首次成功执行时会创建实际数据集。
8. 聚合类型名称并非你所预期的那样
GroupBy 的 type 字段使用 MIN 和 MAX,而非 MINIMUM 或 MAXIMUM。使用 MINIMUM 会返回验证错误:
{"code":"VALIDATION-DIV","message":"The value is invalid for expected type.","path":"actions[2].fields[0].type","parameters":{"field":"type","type":"AggregateType","rejected":"MINIMUM"}}
已确认可用的类型:SUM、AVERAGE、COUNT_ALL、MIN。请使用这些确切的字符串。
9. Filter 的 rightValue 必须是有类型的对象
Filter 操作的 rightValue 不能是普通字符串,必须是有类型的对象:
// WRONG — returns VALIDATION-DE error
"rightValue": "Florida"
// CORRECT
"rightValue": {"value": "Florida", "type": "STRING"}
此外,rightExpr 必须用单引号括住字符串值:"'Florida'"。应同时设置 rightValue 和 rightExpr。
10. TRUNC_MONTH 和其他日期函数不存在
ExpressionEvaluator 不支持 TRUNC_MONTH()、DATE_TRUNC() 或类似的日期截断函数。若要获取年月值,请使用字符串拼接:
concat(year(`date_ymd`), MONTHNAME(`date_ymd`))
已知可用的函数:year()、MONTHNAME()、concat()、DATE()。
11. 通过 CLI 创建的数据流可立即执行(2026 年 4 月更新)
通过 community-domo-cli -y dataflows create 创建的数据流不处于 DRAFT 状态,可以立即使用 community-domo-cli -y dataflows run <ID> 运行。创建时传入 dataSourceId: null 后,outputs 数组会被填充。无需在 UI 中保存。执行会返回有效的执行 ID,并运行至完成。
12. 使用 dataflows run,不要使用 Java CLI
旧版 Java CLI dataflow-run-now 对新创建的数据流可能会返回 500 错误。请始终使用 community-domo-cli -y dataflows run <ID>——它会直接向 /dataprocessing/v1/dataflows/{id}/executions 发送请求,且运行可靠。
13. responsibleUserId 是可选的
无需在 POST 请求正文中指定 responsibleUserId——它默认使用已通过身份验证的用户。
14. LoadFromVault 节点可以连接到多个分支
单个 LoadFromVault 节点可以连接到多个下游分支——只需在多个 dependsOn 数组中引用其 ID。这样可以避免重复加载同一数据集。
15. PublishToVault — 仅使用 dependsOn,不要使用 inputs
PublishToVault 操作使用 dependsOn 引用其上游操作。不要包含 inputs 数组——它不属于可用格式,并会导致 DP-DSCF 提交失败。如果创建后 numOutputs = 0,可能是操作中缺少 dataSource 对象——请 PUT 修正后的定义以解决问题。
16. 身份验证
community-domo-cli 会使用通过 domo login 配置的会话自动处理身份验证。无需手动设置令牌标头或进行 OAuth 交换。
19. 除 LoadFromVault 外,所有操作都必须包含 disabled、removeByDefault、notes
除 LoadFromVault 外,每个操作都必须包含这些字段,否则数据流在 UI 中的行为可能会异常:
"disabled": false,
"removeByDefault": false,
"notes": [],
"previewRowLimit": null
MergeJoin 还必须包含 "on": null,并显式设置 "schemaModification1": [] 和 "schemaModification2": [](即使数组为空也必须设置)。
LoadFromVault 使用 "previewRowLimit": 10000(不能为 null)。
20. relationshipType 必须为 "MTM",不能是 "MANY_TO_MANY"
MergeJoin 字段 relationshipType 必须使用缩写 "MTM"。使用 "MANY_TO_MANY" 会导致验证错误。其他有效值:"OTO"、"OTM"、"MTO"。
21. 构建数据集血缘 ETL 前,务必先询问是否存在主数据集锚点
构建任何数据集血缘 ETL 前,请先询问:“是否存在主‘My Datasets’数据集或类似的列表数据集,所有输出行都应关联到该数据集?” 应将这个锚点数据集(通常包含 Dataset ID、Name、Link、Owner 等)作为最终连接的左侧,以便所有数据集都出现在输出中,包括没有卡片/ETL 关联的独立数据集。缺少这个锚点意味着输出只涵盖恰好出现在其他元数据表中的数据集,会遗漏所有独立数据集。
17. 需要完整的操作数组时,使用 get-definition,而不是 get
community-domo-cli dataflows get 使用 v2 端点,该端点可能不会返回完整的 actions[] 数组。community-domo-cli dataflows get-definition 使用 GET /dataprocessing/v1/dataflows/{id}(不要添加 ?hydrate=full——该参数会导致 400 错误)。发出更新前,务必先使用 get-definition。
18. dataflows update 会替换整个数据流定义
通过 community-domo-cli -y dataflows update <ID> --body-file <FILE> 更新时:
- 发送完整的数据流对象——始终先获取最新的
get-definition,修改后再通过--body-file传入。 - 更新操作只会保存——不会运行数据流。请另行使用
community-domo-cli -y dataflows run <ID>触发执行。 - 版本跟踪——每次成功更新都会递增
onboardFlowVersion.versionNumber。执行响应包含dataFlowVersion,可用于确认运行的是哪个版本。
已知操作类型
在此实例的现有数据流中发现的所有操作类型:
| 操作类型 | 说明 | 已确认可用 |
|---|---|---|
LoadFromVault | 输入节点——加载 Domo 数据集 | 是 |
PublishToVault | 输出节点——写入 Domo 数据集 | 是 |
MergeJoin | 按键连接两个上游操作 | 是 |
GroupBy | 使用 SUM、AVERAGE、MIN、COUNT_ALL 等进行聚合 | 是 |
WindowAction | 排名与窗口——ROW_NUMBER、RANK、LAG、LEAD | 是 |
SelectValues | 旧版选择/重命名节点 | 不适用于此技能中的新流程编写;请使用受支持的转换链 + PublishToVault |
Filter | 根据条件筛选行(NE、EQ、NN 等) | 是 |
ExpressionEvaluator | 添加计算列/公式(concat、year、MONTHNAME、DATE) | 是 |
Unique | 按键列去重 | 已记录(来自模式指南) |
Metadata | 更改列类型或元数据 | 现有数据流中可见 |
SplitColumnAction | 将一列拆分为多列 | 现有数据流中可见 |
FixedInput | 硬编码/常量输入数据 | 现有数据流中可见 |
工作流:创建新的 Magic ETL
准备阶段问题(构建前询问)
- 所有输入数据集 ID 及其列架构是什么?(使用
community-domo-cli datasets sql <UUID> --body '{"sql":"SELECT * FROM table LIMIT 2"}'查询每个数据集) - 是否存在主数据集/锚点数据集(例如“我的数据集”),所有输出行都应关联到该数据集?如果存在,请获取其 UUID——它将作为最终连接的左侧。
- 期望的输出列名称是什么?每个输入字段分别映射到哪一列?
构建步骤
- 获取输入数据集架构 — 对每个输入数据集运行
community-domo-cli datasets sql <UUID> --body '{"sql":"SELECT * FROM table LIMIT 2"}' - 构建 JSON 定义 — 使用本技能文档中已确认可用的操作结构
- 添加彩色 Section 区域 — 在
gui.canvases.default.elements中将相关磁贴分组到 Section 元素中。为每个逻辑分支或处理阶段指定不同的颜色。使用parentId和相对坐标,将 Tile 元素重新设为各 Section 的子元素。对于包含 2 个或更多分支或阶段的所有数据流,此步骤均为必需。 - 创建 —
community-domo-cli -y dataflows create --body-file <FILE>— 可立即生效,无需在界面中保存 - 执行 —
community-domo-cli -y dataflows run <DATAFLOW_ID> - 检查状态 —
community-domo-cli dataflows execution-get <DATAFLOW_ID> <EXEC_ID>— 轮询,直到state为SUCCESS或FAILED_DATA_FLOW - 失败时 — 检查执行响应中的
errors[]数组,查找actionId和localizedMessage,修复相应操作,运行community-domo-cli -y dataflows update <ID> --body-file <FILE>,然后重新运行 - 导出以进行调试 —
community-domo-cli dataflows get-definition <DATAFLOW_ID>会返回完整的已保存定义,其中包含服务器分配的任何 GUID