@ktdatascience

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Snowflakeのタスクで AFTER に別スキーマのタスクを指定できない?

Q&A

Closed

質問

Snowflakeでメダリオンアーキテクチャ(Bronze / Silver / Gold)を構築しています。
スキーマごとにタスクを配置し、AFTER で依存関係を定義しようとしたところ、エラーになりました。

-- ルートタスク(BRONZEスキーマ)
CREATE TASK BRONZE.DAILY_LOAD
  WAREHOUSE = MY_WH
  SCHEDULE = 'USING CRON 0 1 * * * Asia/Tokyo'
AS
  CALL BRONZE.LOAD_ALL(DATEADD(day, -1, CURRENT_DATE()));

-- 子タスク(SILVERスキーマ)→ エラー!
CREATE TASK SILVER.MERGE_DATA
  WAREHOUSE = MY_WH
  AFTER BRONZE.DAILY_LOAD
  WHEN SYSTEM$STREAM_HAS_DATA('BRONZE.MY_STREAM')
AS
  MERGE INTO SILVER.MY_TABLE ...;

完全修飾名(DATABASE.SCHEMA.TASK)で指定しても解決しません。
これはSnowflakeの仕様でしょうか?

0 likes

1Answer

回答

はい、Snowflakeの仕様でした。 タスクグラフ(DAG)内のすべてのタスクは、同一データベース・同一スキーマに存在する必要があります。

公式ドキュメントの記載

CREATE TASK より:

All tasks in a task graph must exist in the same schema.

Task Graphs より:

All tasks in a task graph must have the same task owner and be stored in the same database and schema.

つまり、以下の制約が同時に適用されます:

  • 同一スキーマ:すべてのタスクが同じスキーマに存在すること
  • 同一オーナー:すべてのタスクが同じロールに所有されていること

対処法:タスクを1つのスキーマにまとめる

タスクの配置先を1つのスキーマに統一すれば解決します。タスクが実行するSQL文の中では、他スキーマのオブジェクト(テーブル、ストリーム、プロシージャなど)を完全修飾名で自由に参照できます。

-- すべてのタスクを BRONZE スキーマに配置する例

-- ルートタスク
CREATE TASK BRONZE.DAILY_LOAD
  WAREHOUSE = MY_WH
  SCHEDULE = 'USING CRON 0 1 * * * Asia/Tokyo'
AS
  CALL BRONZE.LOAD_ALL(DATEADD(day, -1, CURRENT_DATE()));

-- 子タスク(BRONZE に配置するが、操作対象は SILVER のテーブル)
CREATE TASK BRONZE.MERGE_DATA
  WAREHOUSE = MY_WH
  AFTER BRONZE.DAILY_LOAD
  WHEN SYSTEM$STREAM_HAS_DATA('BRONZE.MY_STREAM')
AS
  MERGE INTO SILVER.MY_TABLE USING BRONZE.MY_STREAM ...;

-- 子タスク(操作対象は MONITORING のテーブル)
CREATE TASK BRONZE.DATA_QUALITY_CHECK
  WAREHOUSE = MY_WH
  AFTER BRONZE.DAILY_LOAD
AS
  INSERT INTO MONITORING.QUALITY_LOG ...;

ポイント: タスクの「配置場所(スキーマ)」と「操作対象のテーブル」は独立しています。タスクが同一スキーマにあっても、SQL文の中では任意のスキーマのオブジェクトを操作できるため、ロジックへの影響はありません。

環境

  • Snowflake(2025年2月時点の仕様)
0Like

Your answer might help someone💌