Tableau
Tableau Connectorは、Tableauサイトのカタログ(ワークブック、データソース、ビュー、フロー)とビューの裏にあるデータを読み、カタログの項目の名前変更・移動・削除、レコードのデータソースとしての公開、抽出の更新とフロー実行の開始を行います。使い方は2つあります。プログラムがダッシュボードに表示されている内容を読んで行動することも、他の場所に書いたあとで新しいデータをTableauに送り込むこともできます。
読み取り元
tableau.workbooks— サイト上のワークブック。id、name、project_id、project、owner、created_at、updated_at、tags。キーはid。tableau.datasources— パブリッシュ済みのデータソース。id、name、project_id、project、type、has_extract、last_refreshed_at、updated_at、tags。キーはid。tableau.views— ビュー(シートとダッシュボード)。id、name、workbook_id、url、view_count、last_viewed_at。キーはid。tableau.flows— Prepのフロー。id、name、project_id、last_run_at。キーはid。tableau.view_data— ビューの裏にあるレコード。列はビューの列です。view_idで絞り込みます。Connectorはビューのデータをダウンロードし、Tableauのメタデータから列の型を決めます。キーは、ビューのメタデータがキー列を宣言していればその列です。宣言がなければこの読み取り元にはキーがなく、ITEM KEYなしでINFERの対象にすることはできません。
接続は1つのサイトに対応します。別のサイトには2つ目の接続を使ってください。
型
| Tableau | ActQL | 備考 |
|---|---|---|
string、tags | string、array<string> | |
integer、real(ビューのデータ) | int64、float64 | ビューのデータの列の型はビューのメタデータから決まる。real は有限の値だけを受け付ける |
boolean | bool | |
date、datetime | date、timestamp | REST APIのタイムスタンプはUTC |
LUID(id、project_id、workbook_id) | string | 安定した識別子。名前は識別子ではない |
updatedAt | timestamp | 更新時の適用条件にも使う |
書き込みは同じ規則で逆方向に変換します。収まらない値は、静的に分かるなら check で、そうでなければその項目が失敗します。
Effectと操作
レコードのEffectはキーで書きます。
- update —
EFFECT UPDATE tableau.workbooks ID id SET (name = …, project_id = …, tags = …)。tableau.datasourcesにも同じ形で、名前の変更、プロジェクト間の移動、タグの付け替えができます。 - delete —
EFFECT DELETE tableau.workbooks ID idとEFFECT DELETE tableau.datasources ID id。
id はTableauのLUIDで、ちょうど1つの項目を識別します。名前がキーとして受け付けられることはありません。
テーブルとコンテンツ:
- publish —
EFFECT STORE tableau.datasources SET (name = …, project_id = …)は、現在のレコードを新しいパブリッシュ済みデータソースとして公開するか、そのプロジェクトにある同じ名前のものを置き換えます。公開されるのはファイルではなく、レコードそのものです。
操作:
- refresh —
EFFECT COMMAND tableau.refresh TARGET datasource_id ID keyは、対象のデータソースの抽出の更新を開始します。 - run_flow —
EFFECT COMMAND tableau.run_flow TARGET flow_id ID keyは、Prepのフローの実行を開始します。
どちらもTableauに受け付けられ、バックグラウンドのジョブとして実行されます。項目はジョブIDとともに accepted で終わり、ジョブが完了する前にRunが終わることがあります。ジョブ自体の結果は別の作業で、あとからジョブ一覧で読みます。
セットアップ
"tableau": {
"connector": "tableau",
"server": "https://tableau.acme.com",
"site": "analytics",
"credentials": {
"token_name": "actql",
"token_secret": {"env": "TABLEAU_PAT_SECRET"}
}
}プログラムが読むワークブック、データソース、フローを閲覧でき、書き込み先のプロジェクトにパブリッシュでき、抽出の更新とフローを実行できるサイトロールを持つユーザーの、個人用アクセストークンを作ります。Tableau CloudとTableau Serverの設定は同じです。ActQL Cloudでも項目は同じで、トークンのシークレットはCloudのシークレットストアに保存します。
Capabilityとプッシュダウン
| 演算 | プッシュダウンされる条件 |
|---|---|
| 列の選択 | カタログの読み取り元では常に。view_data はビューの全列をダウンロードし、Hostで列を選ぶ |
WHERE | カタログの読み取り元で、name、project_id、owner、tags、日時の列に対する =、IN、<、> のとき。REST APIのフィルター式で表せる範囲。view_data に対する述語はすべてHostで実行する |
ORDER BY、LIMIT | カタログの読み取り元で、name と日時の列によるとき。ページングは1ページ100件 |
AGGREGATE、JOIN | されない。どちらもHostで実行する |
explain は、カタログの読み取りをSite connector:tableau、Engine Tableau REST で表示します。view_data はまるごと読み、それに対する処理はすべてHostで実行します。
プレビューと突き合わせ
プレビュー。 更新と削除は full_diff です。ConnectorはLUIDで項目を読み、現在の名前、プロジェクト、タグを記録し、プレビューには現在の値と新しい値が出ます。送るリクエストには、そのとき見た updatedAt が付きます。その間に変わった項目は failed(conflict)で終わり、続けるよう求められればRunは新しいプレビューを作ります。パブリッシュは、データソースの名前、プロジェクト、公開する件数、既存のデータソースを置き換えるかどうかをプレビューします(targeted)。更新処理とフロー実行は、対象と、ジョブが開始されることをプレビューします(targeted)。
突き合わせ。 更新処理とフロー実行はどれもジョブです。ConnectorはTableauがジョブIDを返した時点でそれを記録し、応答が失われた場合はジョブ一覧でそのジョブを探して突き合わせます。同じデータソースに対する最近のジョブでも、Connectorが開始したものでなければ証跡になりません。パブリッシュでは、リクエストのマーカーをデータソースの説明に入れます。応答が失われた場合は、データソースを名前で探してマーカーを確認します。名前は合っていてもマーカーがないデータソースは、項目を unknown のまま残します。更新と削除にはTableauが保持するマーカーがなく、REST APIはリクエストIDも記録しないので、応答が失われた更新と削除は unknown のままです。項目が承認された値を持っていることや、リクエストの時間帯の updatedAt は証跡になりません。推測で再送することはありません。
上限と費用
- REST APIは1ページ100件で、サイトごとにレート制限があります。Connectorはその範囲内でペースを調整し、プログラムの件数の上限に達したら、途中までの結果ではなくエラーで止まります。
- ビューのデータのダウンロードは、プログラムのバイト数の上限で抑えられます。非常に大きなビューは、代わりにその元になるDWHのテーブルから読んでください。
- 更新処理とフロー実行は、サイトのバックグラウンドジョブの容量を使います。Tableau Cloudではサイトのジョブ上限にも数えられます。Runはジョブidを記録するので、費用を追跡できます。
- パブリッシュはデータソース全体を置き換えます。置き換えられた抽出は、そのあとTableauが作り直します。
例
90日間だれも開いていないビューです。
FROM tableau.views AS v
JOIN tableau.workbooks AS w ON v.workbook_id = w.id
|> WHERE v.last_viewed_at < TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 90 DAY)
|> SELECT w.project, w.name AS workbook, v.name AS view
|> ORDER BY w.project, w.name;新しいスコアを書き込んだあとで、解約ダッシュボードのデータソースを更新します。
FROM tableau.datasources
|> WHERE name = 'Churn Risk Scores'
|> EFFECT COMMAND tableau.refresh TARGET id ID id;LLMの判定を、ダッシュボードから使えるデータソースとして公開します。
SELECT a.id AS account_id, a.name, risk.value.level AS level, risk.value.reason AS reason
FROM salesforce.accounts AS a
JOIN snowflake.usage_30d AS u ON a.id = u.account_id
|> INFER `model-task:churn-risk.v1`
INPUT (notes = a.description, active_users = u.active_users, trend = u.trend) AS risk
|> WHERE risk.outcome = 'ok'
|> EFFECT STORE tableau.datasources SET (name = 'Churn Risk Scores', project_id = @project);Source: actql/actql/docs/connectors/tableau.md at d904416674e4 · Edit on GitHub