magic-etl について
magic-etl は、API と Java CLI を使って Domo Magic ETL のデータフローを作成、更新、実行する方法を解説するスキルです。JSON DAG で変換を定義し、実行やキャンバスのレイアウトを管理する Domo ユーザー向けです。
主な機能
- 01REST API によるデータフローの作成と更新
- 02Java CLI による一覧表示、エクスポート、実行、確認
- 03JSON DAG としてのデータフローアクション定義
- 04データセットの入力、出力、実行動作の設定
- 05セクションと配置したタイルによるキャンバス整理
活用シーン
- 01データセット入力と変換から Magic ETL データフローを構築する
- 02既存のデータフロー定義をエクスポートして構造を調べる
- 03データフローを実行し、状態と結果を確認する
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ stahura/ domo-ai-vibe-rules --skill magic-etlインストール後、Claude Code で/magic-etlを入力して読み込まれたか確認します。
詳細
Domo で Magic ETL データフローをプログラムで作成する
概要
Domo の Magic ETL データフローは、API を通じて作成、更新、実行できます。データフローは、アクション(入力ノード、変換、出力ノード)で構成される有向非巡回グラフ(DAG)を記述した JSON ドキュメントとして定義します。
CLI 優先:読み取り/実行操作には Java CLI を使用し、作成には REST API を使用します。
| 操作 | CLI を使用? | REST API を使用? |
|---|---|---|
| データフローの一覧表示 | list-dataflow -dt MAGIC | — |
| データフロー定義のエクスポート | list-dataflow -i <ID> -d -f <FILE> | — |
| データフローの実行 | dataflow-run-now -i <ID> | POST .../executions(新しいデータフローではより信頼性が高い) |
| 実行ステータスの確認 | list-dataflow -i <ID> -e -l 1 | GET .../executions?limit=1 |
| 作成 | — | POST /api/dataprocessing/v1/dataflows(開発者トークンで動作し、直ちに実行可能) |
| 更新 | set-dataflow-properties -i <id> -d <file> | PUT /api/dataprocessing/v1/dataflows/<ID> |
| 名前変更/有効化 | set-dataflow-properties -i <id> -n/-e/-s | PUT /api/dataprocessing/v1/dataflows/<ID>/patch |
重要: API(POST)を使ったデータフローの作成は開発者トークンで動作します(2026 年 4 月に確認済み)。作成したデータフローは直ちに実行できます。domo(ryuu)CLI はカスタムアプリの公開専用です。データフロー操作には Java CLI(domoutil.jar)を使用してください。
データフローの CLI コマンド
すべての Magic ETL データフローを一覧表示
list-dataflow -dt MAGIC
データフロー定義を取得(JSON にエクスポート)
list-dataflow -i <DATAFLOW_ID> -d -f <OUTPUT_FILE>
これにより、すべてのアクション、入力、出力、GUI の位置を含む完全な JSON 定義がエクスポートされます。JSON 構造を理解する最善の方法は、既存のデータフローをエクスポートして調べることです。
データフローを実行
dataflow-run-now -i <DATAFLOW_ID>
データフローの実行履歴を一覧表示
list-dataflow -i <DATAFLOW_ID> -e -l <LIMIT>
API で実行ステータスを確認
curl -s "https://<instance>.domo.com/api/dataprocessing/v1/dataflows/<ID>/executions?limit=1&offset=0" \
-H "x-domo-developer-token: <TOKEN>"
実行状態(SUCCESS、FAILED_DATA_FLOW、CREATED、RUNNING)、行数、エラーなどを返します。
API を使ったデータフローの作成
エンドポイント
POST https://<instance>.domo.com/api/dataprocessing/v1/dataflows
認証(2026 年 3 月): このエンドポイントには開発者トークンではなく、SID ベースの認証が必要です。開発者トークンでは 403 Forbidden が返されます。SID 交換を使用してください:リフレッシュトークン → oauth2/token → アクセストークン → oauth2/sid → SID。
ヘッダー:
Content-Type: application/json
X-Domo-Authentication: <SID>
本文には "databaseType": "MAGIC" を含める必要があります。作成したデータフローは直ちに実行できます。詳細は注意点 #7 と #11 を参照してください。
注:
x-domo-developer-tokenは、POST(作成)、GET、PUT、実行を含むすべてのデータフロー操作で機能します(2026 年 4 月に確認済み)。
既存のデータフローを更新
PUT https://<instance>.domo.com/api/dataprocessing/v1/dataflows/<DATAFLOW_ID>
POST と同じヘッダーおよび本文形式を使用します。完全な定義を含めてください。
データフローの 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) |
トップレベルの 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
}
}
セクション要素(色付き背景ゾーン)
セクションは、キャンバス上で関連するタイルを視覚的にグループ化する色付きの長方形ゾーンです。
{
"id": "a-unique-uuid",
"type": "Section",
"x": 56,
"y": 72,
"width": 1320,
"height": 288,
"name": "Work Orders Denormalization",
"backgroundColor": "var(--colorChartBlue6)"
}
| フィールド | 説明 |
|---|---|
id | セクションの一意な UUID |
type | "Section" である必要があります |
x、y | キャンバス上の絶対位置(左上の角) |
width、height | 色付きゾーンのピクセル単位のサイズ |
name | セクションヘッダーに表示されるラベル |
backgroundColor | ゾーンの色を指定する CSS 変数(下の表を参照) |
使用可能なセクション背景色
| CSS 変数 | 色 | 推奨用途 |
|---|---|---|
var(--colorChartBlue6) | ライトブルー | 入力/ステージングパイプライン |
var(--colorChartGreen6) | ライトグリーン | 品質/検証パイプライン |
var(--colorChartPurple6) | ライトパープル | 出力/公開パイプライン |
var(--colorChartOrange6) | ライトオレンジ | 変換/エンリッチメントパイプライン |
var(--colorChartRed6) | ライトレッド | フィルター/除外パイプライン |
var(--colorChartYellow6) | ライトイエロー | 共有/ディメンションテーブル |
接尾辞の 6 は最も明るい色合いを示します。セクションの背景に最適で、タイルのラベルが読みやすくなります。
タイル要素(アクションの位置)
各アクションノードには、キャンバス上に対応する Tile 要素があります。タイルはセクション内に親子付けできます。その場合、x/y はセクションの位置を基準とした相対座標になります。
{
"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 が設定されている場合は親セクションを基準とした相対座標 |
parentId | 親セクション要素の UUID(タイルを親子付けしない場合は省略) |
color | タイルアイコンの任意の整数色コード |
親子付けの座標変換式: タイルをセクション内に移動する場合、絶対座標を相対座標に変換します。
relativeX = absoluteX - section.xrelativeY = absoluteY - section.y
parentId のないタイルは、キャンバスの絶対座標に配置され、どのセクションにも属さずに表示されます。
データフローを作成するときは必ずセクションを追加する
複数の論理ブランチや処理段階を持つデータフローを作成する場合、視覚的なレイアウトを整理するために必ずセクション要素を追加してください。これは、データフローをひと目で理解しやすくするベストプラクティスです。次の単位でタイルをグループ化します。
- パイプラインのブランチ(例:各ファクトテーブルの結合チェーンに独自のセクションを割り当てる)
- 処理段階(例:「入力/ステージング」、「変換」、「出力」)
- 共有リソース(例:複数のブランチで使用するディメンションテーブル)
各セクションに異なる色を割り当て、視覚的に区別できるようにします。
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 を通じて上流の依存関係を参照します。
共通アクションフィールド
すべてのアクションには、次のフィールドがあります。
{
"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(結合)
指定したキーを使用して、2 つの上流アクションを結合します。
{
"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
2 つのデータセットに同じ列名(たとえば、両方に 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 では MINIMUM や MAXIMUM ではなく、MIN と MAX を使用します。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 の前に ExpressionEvaluator を用意しなくても、CASE WHEN などの複雑なロジックを GroupBy に直接組み込めます。
{
"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
}
WindowAction(ランクとウィンドウ)
グループ列でパーティション分割し、ソート列で並べ替えて、ウィンドウ関数(ランキング、行番号、LAG/LEAD オフセット)を適用します。Magic ETL UI の「ランクとウィンドウ」タイルに相当するプログラム上の処理です。
{
"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 | ASC の場合は true、DESC の場合は 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 は、すべての元の列に新たに追加した列を加えて後続に渡すため、後続のアクションからすべての列にアクセスできます。
Filter(行のフィルタリング)
列の条件に基づいて行をフィルタリングします。Magic ETL UI の「行をフィルタリング」タイルに相当するプログラム上の処理です。
{
"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": []
}
複数の条件を含むフィルターや、関数呼び出しを含むフィルターに便利です。expression は 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() | 左側の部分文字列 | 「2025-01-15」から年月を取得する場合は LEFT(\Date`, 7)` |
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 列を作成できます
1 つの 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を省略します
代替形式 — select の代わりに fields を使用します。保持する列のみを指定してください(必要に応じて名前を変更)。指定されていない列は削除されます。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-output",
"name": "SFDC | Account Summary",
"dependsOn": ["MergeJoin-final"],
"disabled": false,
"removeByDefault": false,
"notes": [],
"settings": {"preferredDatabaseEntityType": "TEMP_VIEW"},
"gui": {"x": 1248, "y": 320, "color": null, "colorSource": null, "sampleJson": null},
"previewRowLimit": null,
"dataSource": {
"type": "DataFlow",
"name": "SFDC | Account Summary",
"cloudId": "domo"
},
"versionChainType": "REPLACE",
"partitionIdColumns": [],
"upsertColumns": [],
"retainPartitionExpression": ""
}
| フィールド | 説明 |
|---|---|
dependsOn | 単一のアクション ID を含む配列 — 最終の変換ステップ |
dataSource.type | "DataFlow" |
dataSource.name | 出力データセットの名前 |
dataSource.guid | 既存の出力データセットの UUID — 新しいデータセットの場合は完全に省略します |
dataSource.cloudId | "domo" |
versionChainType | "REPLACE"(全件置換)または "APPEND" |
partitionIdColumns | [] — パーティショニングを使用する場合を除き、常に空にします |
upsertColumns | [] — アップサートを行う場合を除き、常に空にします |
retainPartitionExpression | "" — 常に空文字列にします |
重要: PublishToVault に inputs、schemaSource、partitioned、tables を含めないでください。これらのフィールドがあると DP-DSCF のコミットに失敗します。その場合、ETL はすべての行を正常に処理した後、出力データセットへの書き込みに失敗します。これは広範なテストを通じて確認されています(2026年4月)。
新しいデータフローでは、guid を完全に省略します。初回の実行が成功すると、Domo が実際の出力データセット UUID を割り当てます。
完全な例:アカウント概要 ETL
この例では、次の処理を行うデータフローを作成します。
- 3つの Salesforce データセット(Accounts、Contacts、Opportunities)を読み込みます
- アカウントごとに連絡先を集計します(件数)
- アカウントごとに商談を集計します(件数、合計金額、平均金額、予想売上、平均確度)
- 2つの集計結果を Accounts テーブルに左結合します
- すべての概要指標を含む、アカウントごとに1行のデータを出力します
パイプライン図
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
作成コマンド
curl -s -X POST "https://<instance>.domo.com/api/dataprocessing/v1/dataflows" \
-H "Content-Type: application/json" \
-H "x-domo-developer-token: <TOKEN>" \
-d @sfdc_account_summary_etl.json
実行
# Via CLI
echo -e "connect -server <instance>.domo.com -token <TOKEN>\ndataflow-run-now -i <DATAFLOW_ID>\nquit" \
| java -jar domoutil.jar
# Via API
curl -s -X POST "https://<instance>.domo.com/api/dataprocessing/v1/dataflows/<ID>/executions" \
-H "x-domo-developer-token: <TOKEN>"
完全な例:ランクとウィンドウ関数を使った顧客概要
この例では、次の処理を行うデータフローを作成します。
- 顧客、日付、売上、収益、売上原価を含む財務データセット(329,460行)を読み込みます
- WindowAction を使用し、日付順に顧客ごとの注文をランク付けします(ROW_NUMBER)
- 顧客ごとに集計します。初回注文日(MIN)、売上/収益/売上原価の合計と平均、注文数
パイプライン図
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(Rank & Window タイル):
{
"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
}
}
]
}
初回注文日に MIN を使用する GroupBy:
{
"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行(顧客ごとに1行)。列: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 の合計と平均を計算します
パイプライン図
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行(月 × 部門 × metric_name ごとに1行、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 で確認します |
エラーを特定のタイルまで追跡する
エラーオブジェクトには、失敗したタイルの _actionId(UUID)を含む parameters マップがあります。データフロー内の 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 コミットエラー — PublishToVault の構造が正しくない
"Failed to commit data to data source <UUID>" というエラー(コード DP-DSCF)は、PublishToVault のフィールドが正しくない場合に発生します。ETL はすべての行を正常に処理しますが、コミットの段階で失敗します。
根本原因(2026 年 4 月に確認): PublishToVault アクションで inputs、schemaSource、partitioned、または tables を使用していることです。
修正方法: 次の構造をそのまま使用します。partitionIdColumns、upsertColumns、retainPartitionExpression を指定し、inputs、schemaSource、partitioned、tables は省略します。
{
"type": "PublishToVault",
"dataSource": {"type": "DataFlow", "name": "Output Name", "cloudId": "domo"},
"versionChainType": "REPLACE",
"partitionIdColumns": [],
"upsertColumns": [],
"retainPartitionExpression": ""
}
2. SelectValues の fields 形式 — 残す列だけを指定する
SelectValues の fields 形式では、"remove": true を含むエントリーや type、dateFormat、settings などの追加フィールドを含めると、DP-0003 Action is improperly configured が発生します。残す列だけを指定してください。
"fields": [
{"name": "ID", "rename": "Dataset ID"},
{"name": "Name", "rename": "Dataset Name"}
]
指定されていない列は自動的に削除されます。削除エントリーは追加しないでください。
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 フィールドではなく、トップレベルの gui.canvases.default.elements 配列で制御されます。一貫性を保つため、両方を必ず設定してください。Section および Tile 要素のスキーマ全体については、「トップレベルの gui フィールド」セクションを参照してください。
7. API 経由でのデータフロー作成 — 認証(2026 年 4 月更新)
認証: POST /api/dataprocessing/v1/dataflows は、ほとんどのインスタンスで開発者トークン(DDCI...)を使用できます(2026 年 4 月に確認済み)。リクエストボディには "databaseType": "MAGIC" を必ず含める必要があります。作成されたデータフローは DRAFT 状態ではなく、UI で保存しなくても API 経由ですぐに実行できます。
出力: POST に "outputs": [{"dataSourceId": null, "dataSourceName": "...", "versionChainType": "REPLACE"}] を含めると、Domo によって実際の出力データセット UUID がすぐに割り当てられます。最初の実行が成功すると、実際のデータセットが作成されます。
CLI: domo(ryuu)CLI はカスタムアプリの公開専用で、データフロー関連のコマンドはありません。Java CLI(domoutil.jar)にはデータフロー関連のコマンドがありますが、別途セットアップが必要です。
8. 集計タイプ名は想定と異なります
GroupBy の type フィールドでは MINIMUM や MAXIMUM ではなく、MIN と MAX を使用します。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. POST 経由で作成したデータフローはすぐに実行できます(2026 年 4 月更新)
以前の記述とは異なり、開発者トークンを使用して POST /api/dataprocessing/v1/dataflows 経由で作成したデータフローは DRAFT 状態ではなく、POST .../executions 経由ですぐに実行できます。dataSourceId: null を渡すと、作成時に outputs 配列が設定されます。UI での保存は不要です。実行すると有効な実行 ID が返され、処理が完了するまで実行されます。
12. 新しいデータフローでは CLI の dataflow-run-now が失敗することがあります
Java CLI の dataflow-run-now コマンドは、新しく作成されたデータフローに対して 500 エラーを返すことがあります。実行には常に API(POST /api/dataprocessing/v1/dataflows/{id}/executions)を使用してください。こちらのほうが信頼性があります。
13. responsibleUserId は省略できます
POST のリクエストボディで responsibleUserId を指定する必要はありません。認証済みユーザーがデフォルトで設定されます。
14. LoadFromVault ノードから複数の分岐にデータを渡せます
1 つの LoadFromVault ノードから複数の下流分岐にデータを渡せます。複数の dependsOn 配列でその ID を参照するだけです。これにより、同じデータセットを二重にロードせずに済みます。
15. PublishToVault — inputs ではなく dependsOn のみを使用します
PublishToVault アクションでは、上流のアクションを参照するために dependsOn を使用します。inputs 配列は含めないでください。これは動作する形式の一部ではなく、DP-DSCF のコミット失敗の原因になります。作成後に numOutputs が 0 の場合、アクションに dataSource オブジェクトがない可能性があります。定義を修正して PUT してください。
16. API トークン認証
REST API では、CLI と同じ開発者トークンを使用します。
x-domo-developer-token: <TOKEN>
OAuth とは異なり、クライアント ID/シークレットの交換は必要ありません。
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 は "MANY_TO_MANY" ではなく "MTM" にする必要があります
MergeJoin のフィールド relationshipType には、省略形の "MTM" を指定する必要があります。"MANY_TO_MANY" を使用すると、検証エラーが発生します。その他の有効な値は "OTO"、"OTM"、"MTO" です。
21. リネージュ ETL の構築前に、必ずマスターデータセットをアンカーとして使うか確認してください
データセットのリネージュ ETL を構築する前に、次の点を確認してください。「すべての出力行を関連付ける必要がある、マスターの『My Datasets』または同様の一覧データセットはありますか?」 このアンカーデータセット(通常は Dataset ID、Name、Link、Owner などを含みます)は、すべてのデータセットが出力に含まれるよう、最終結合の LEFT 側に読み込む必要があります。カードや ETL との関連付けがない単独のデータセットも対象になります。このアンカーがないと、出力対象は他のメタデータテーブルに存在するデータセットに限られ、単独のデータセットが漏れてしまいます。
17. データフローの取得時に ?hydrate=full を使用しないでください
GET /api/dataprocessing/v1/dataflows/{id}?hydrate=full は、一部のデータフローで 400 Bad Request を返します。ハイドレーションなしのエンドポイント(GET /api/dataprocessing/v1/dataflows/{id})でも、すべてのタイル詳細を含む完全な actions[] 配列が返されます。必ずハイドレーションなしのバージョンを使用してください。
18. PUT はデータフロー定義全体を置き換えます
PUT /api/dataprocessing/v1/dataflows/{id} でデータフローを更新する場合:
- データフローオブジェクト全体を送信してください — PUT は定義全体を置き換えます。必ず最新の GET の結果を元にしてください。
- PUT は保存のみを行います — データフローは実行しません。
POST .../executionsで別途実行を開始してください。 - バージョン追跡 — PUT が成功するたびに
onboardFlowVersion.versionNumberが増加します。実行レスポンスには、どのバージョンが実行されたかを確認できるdataFlowVersionが含まれます。
既知のアクションタイプ
インスタンス内の既存のデータフロー全体で確認された、すべてのアクションタイプ:
| アクションタイプ | 説明 | 動作確認済み |
|---|---|---|
LoadFromVault | 入力ノード — Domo データセットを読み込みます | はい |
PublishToVault | 出力ノード — Domo データセットに書き込みます | はい |
MergeJoin | キーを使って2つの上流アクションを結合します | はい |
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 と、それぞれの列スキーマは何ですか?(各データセットに対して
/api/query/v1/execute/<UUID>を使い、SELECT * FROM table LIMIT 2を実行します) - すべての出力行を関連付ける、マスター/アンカーデータセット(例:「My Datasets」)はありますか?ある場合は UUID を取得してください。これが最終結合の LEFT 側になります。
- 目的の出力列名と、それぞれに対応する入力フィールドは何ですか?
ビルド手順
- 入力データセットのスキーマを取得する — 各入力データセットで
POST /api/query/v1/execute/<UUID>を実行し、{"sql": "SELECT * FROM table LIMIT 2"}を指定します - JSON 定義を作成する — このスキルのドキュメントに記載されている、動作確認済みのアクション構造を使用します
- 色付きのセクションゾーンを追加する — 関連するタイルを
gui.canvases.default.elements内のセクション要素にまとめます。論理分岐または処理ステージごとに異なる色を割り当てます。parentIdと相対座標を使って、タイル要素をそれぞれのセクションに配置します。この手順は、2 つ以上の分岐またはステージがあるすべてのデータフローで必須です。 - API で作成する — 開発者トークンを使って
POST /api/dataprocessing/v1/dataflowsを実行します。すぐに反映されるため、UI で保存する必要はありません - 実行する —
POST /api/dataprocessing/v1/dataflows/<ID>/executions - ステータスを確認する —
GET /api/dataprocessing/v1/dataflows/<ID>/executions/<EXEC_ID>を実行し、stateがSUCCESSまたはFAILED_DATA_FLOWになるまでポーリングします - 失敗した場合 — 実行レスポンスの
errors[]配列でactionIdとlocalizedMessageを確認し、該当するアクションを修正して、更新した定義をPUTで送信してから再実行します - デバッグ用にエクスポートする —
GET /api/dataprocessing/v1/dataflows/<ID>を実行すると、サーバーが割り当てた GUID を含む、保存済みの定義全体が返されます