❄️

Snowflakeでautocommitをfalseにする際の注意事項

に公開

概要

SnowflakeのGUI、Snowsightにて、内部ステージにローカルからファイルをアップロード(ステージング)する要件があるとします。このとき、autocommitパラメータの値により挙動が変わります。

準備

普通に内部ステージを作ります。今回の機能を利用するためには内部ステージのディレクトリテーブルの有効化がほぼ必須のため、有効化します。

use role sysadmin;
use warehouse compute_wh;
create database tmp_db;
use schema tmp_db.public;
create stage tmp_db.public.tmp_internal_stage1 directory=(enable=true);
create stage tmp_db.public.tmp_internal_stage2 directory=(enable=true);

内部ステージにファイルをアップロードする

要件によりSnowsightを通じて内部ステージにファイルをアップロードしなければならないのでファイルをアップロードします。
データベースエクスプローラーから対象のステージを選択し、右上の[+ ファイル]ボタンからファイルをアップロードできます。

ディレクトリテーブルを有効化しているため、アップロード後にファイル一覧が更新されます。裏ではALTER STAGE IDENTIFIER('"TMP_DB"."PUBLIC"."TMP_INTERNAL_STAGE1"') refreshが実行されており、ウェアハウスの表示名の右の更新マークボタンからも同様のクエリをGUI経由で実行可能です。

autocommitパラメータによる挙動の変化

ユーザレベルでautocommitfalseにします。

alter user "<USER NAME>" set autocommit = false;

この状態でtmp_internal_stage2を対象に同じくファイルをアップロードすると、アップロードができたような感じはするもののその後ファイル一覧が更新されなかったり、更新ボタンを押しても反応がなかったり(正確には5分程度トランザクションブロックされた後に特にファイル一覧が更新されない現象が起きる)、トランザクションに関するエラーメッセージが表示される等されます。

ちなみにLISTは意図通りに動き、ファイルを表示します。refreshlistは別の仕組みのため、だからといってここに解決の糸口はありません。

ls @tmp_db.public.tmp_internal_stage2;

結論

※2025年9月現在

この話に救いはなく、単純にautocommit = falseの環境下ではGUIでのファイルのステージング機能は利用できません。アカウントレベルでこのパラメータが設定されている場合、この操作を実行したいユーザに対し例外的にユーザレベルでtrueにする必要があります。

特に公式ドキュメントにも記載はありません。
https://docs.snowflake.com/en/user-guide/data-load-local-file-system-stage-ui
https://docs.snowflake.com/en/sql-reference/transactions

この話が、アカウントレベルでのautocommitを敢えてfalseにしている環境で、かつGUIでのファイルのアップロードをしなければならない要件を持つ人に届くと幸いです。

おまけ

autocommit関連のおまけtipsです。

アカウントレベルでautocommit = falseの環境下で、taskからトランザクションを伴うprocedureをcallする必要があるとします。
このとき、公式ドキュメントを読むとautocommitをtrueにする必要がある旨が記載されています。
https://docs.snowflake.com/en/sql-reference/sql/create-task#usage-notes

CREATE TASKのSyntaxを見ると、

[ <session_parameter> = <value>
      [ , <session_parameter> = <value> ... ] ]

と記載があるため、ここにautocommit = trueを仕込むことが可能です。

もしくは、procedureで明示的にトランザクションを制御する必要があります。

Discussion