Snowflakeデータロード時のエラー対応
今回は外部テーブルからデータをロードする際のエラーについてです。
前回の記事の続きです。
ロード時のエラーオプション
- ON_ERROR = 'CONTINUE' → エラー行以外をロードする
- ON_ERROR = 'ABORT_STATEMENT' → エラーの時点でロードを停止
- ON_ERROR = 'SKIP_FILE' → エラーがあったファイルだけスキップ
- ON_ERROR = 'SKIP_FILE={number}' → エラーがあった行数でスキップorロード
- ON_ERROR = 'SKIP_FILE={number}%' → エラーがあった行数の割合でスキップorロード
ON_ERROR = 'CONTINUE'
わざとエラーを起こしてみる
CREATE OR REPLACE STAGE MANAGE_DB.external_stages.aws_stage_errorex
url='s3://bucketsnowflakes4'
CREATE OR REPLACE TABLE OUR_FIRST_DB.PUBLIC.ORDERS_EX (
ORDER_ID VARCHAR(30),
AMOUNT INT,
PROFIT INT,
QUANTITY INT,
CATEGORY VARCHAR(30),
SUBCATEGORY VARCHAR(30));
COPY INTO OUR_FIRST_DB.PUBLIC.ORDERS_EX
FROM @MANAGE_DB.external_stages.aws_stage_errorex
file_format= (type = csv field_delimiter=',' skip_header=1)
files = ('OrderDetails_error.csv');
エラー内容
Numeric value 'one thousand' is not recognized ファイル「OrderDetails_error.csv」、行 2、文字 14 行 1、列 "ORDERS_EX"["PROFIT":3] エラーが発生してもロードを継続したい場合は、ON_ERRORオプションに「SKIP_FILE」または「CONTINUE」などの別の値を使用します。ロードのオプションの詳細については、SQLクライアントで「info loading_data」を実行してください。
Udemyに講座を受けていただければよりエラーが起きた原因が分かるのですが、
端的に言うとINT型で用意したカラムにOne thousand
という文字列型がきており読み込めませんってエラーです。
エラー時のデフォルトの動作
エラーが発生した場合、下図の通りデータは読み込まれません。
ON_ERROR = 'CONTINUE'でエラー行をスキップ
ON_ERROR = 'CONTINUE'オプションを利用すると、エラー行をスキップしてくれる動作となります。
確認してみます。
COPY INTO OUR_FIRST_DB.PUBLIC.ORDERS_EX
FROM @MANAGE_DB.external_stages.aws_stage_errorex
file_format= (type = csv field_delimiter=',' skip_header=1)
files = ('OrderDetails_error.csv')
ON_ERROR = 'CONTINUE';
ロードの結果を見てみると、rows_loadedが1498で2行読み込めていないことが分かります。
first_errorではエラー内容を確認できます。今回は「Numeric value 'one thousand' is not recognized」となっていました。
テーブルの確認
SELECT * FROM OUR_FIRST_DB.PUBLIC.ORDERS_EX
取り込み業が1498となっているのでエラーの2行だけ取り込まれずそれ以外は取り込まれた感じですね。
ON_ERROR = 'ABORT_STATEMENT'
ON_ERROR = 'ABORT_STATEMENT'を利用します
一旦先ほど取り込んだデータはトランケートしておきます。
TRUNCATE TABLE OUR_FIRST_DB.PUBLIC.ORDERS_EX;
ON_ERROR = 'ABORT_STATEMENT'を使って再度取り込み実施
COPY INTO OUR_FIRST_DB.PUBLIC.ORDERS_EX
FROM @MANAGE_DB.external_stages.aws_stage_errorex
file_format= (type = csv field_delimiter=',' skip_header=1)
files = ('OrderDetails_error.csv','OrderDetails_error2.csv')
ON_ERROR = 'ABORT_STATEMENT';
実行結果
御覧の通りON_ERRORオプション無しの時と同じエラーです。つまりABORT_STATEMENTは付けても付けなくても動作は同じということです。
また取り込み対象データが複数あった場合、1つ目のファイルでエラーとなればそれ以降のファイルでのコピーは停止します。
Numeric value 'one thousand' is not recognized ファイル「OrderDetails_error.csv」、行 2、文字 14 行 1、列 "ORDERS_EX"["PROFIT":3] エラーが発生してもロードを継続したい場合は、ON_ERRORオプションに「SKIP_FILE」または「CONTINUE」などの別の値を使用します。ロードのオプションの詳細については、SQLクライアントで「info loading_data」を実行してください。
ON_ERROR = 'SKIP_FILE'
ON_ERROR = 'SKIP_FILE'を利用します
COPY INTO OUR_FIRST_DB.PUBLIC.ORDERS_EX
FROM @MANAGE_DB.external_stages.aws_stage_errorex
file_format= (type = csv field_delimiter=',' skip_header=1)
files = ('OrderDetails_error.csv','OrderDetails_error2.csv')
ON_ERROR = 'SKIP_FILE';
結果を確認してみると、status欄でLOAD_FAILEDとなっているファイルはrows_loadedが0なのでこのファイルはエラーが起きロードをスキップしたようです。
反対にstatus欄でLOADEDとなっているファイルは285行読み込まれています。
ON_ERROR = 'SKIP_FILE={number}'
ON_ERROR = 'SKIP_FILE={number}'を利用します
SKIP_FILE_2の場合エラー行が2行以上ならスキップし、2行以下ならエラー行以外を読み込みます。
COPY INTO OUR_FIRST_DB.PUBLIC.ORDERS_EX
FROM @MANAGE_DB.external_stages.aws_stage_errorex
file_format= (type = csv field_delimiter=',' skip_header=1)
files = ('OrderDetails_error.csv','OrderDetails_error2.csv')
ON_ERROR = 'SKIP_FILE_2';
なので今回のデータは2行のエラーがありますので、下図の通りエラーがあったファイルはスキップされます。
ではSKIP_FILE_3にするとどうなるか?
エラー行数が2行なのでスキップされずにエラー行以外が読み込まれるはずです。
COPY INTO OUR_FIRST_DB.PUBLIC.ORDERS_EX
FROM @MANAGE_DB.external_stages.aws_stage_errorex
file_format= (type = csv field_delimiter=',' skip_header=1)
files = ('OrderDetails_error.csv','OrderDetails_error2.csv')
ON_ERROR = 'SKIP_FILE_3';
結果は・・・想定通りでした。
行数判定ではなく、割合判定もあります。
ON_ERROR = 'SKIP_FILE_0.5%'とすることで、ファイル内で見つかったエラー行の割合が指定された割合を超えた場合は、ファイルをスキップします。
Discussion