File Formatは、Snowflakeにデータをロード(COPY INTO <table>)または アンロード(COPY INTO <location>)する際のファイル形式とパースオプションを定義する 再利用可能なオブジェクトです。CSV・JSON・Parquet・Avro・ORCの5つの形式をサポートし、 各形式固有のオプション(区切り文字・圧縮・エラー処理など)を一元管理できます。
-- 基本的なCSV File Format
CREATE OR REPLACE FILE FORMAT util_db.formats.csv_standard
TYPE = 'CSV'
FIELD_DELIMITER = ','
RECORD_DELIMITER = '\n'
SKIP_HEADER = 1
FIELD_OPTIONALLY_ENCLOSED_BY = '"'
NULL_IF = ('NULL', 'null', '\N', '')
EMPTY_FIELD_AS_NULL = TRUE
COMPRESSION = 'AUTO';
-- パイプ区切りのCSV(レガシーシステム連携向け)
CREATE OR REPLACE FILE FORMAT util_db.formats.csv_pipe
TYPE = 'CSV'
FIELD_DELIMITER = '|'
RECORD_DELIMITER = '\n'
SKIP_HEADER = 0
ESCAPE = '\\'
ESCAPE_UNENCLOSED_FIELD = '\\'
TRIM_SPACE = TRUE;
-- エラー許容CSVフォーマット(データ品質が不安定な場合)
CREATE OR REPLACE FILE FORMAT util_db.formats.csv_tolerant
TYPE = 'CSV'
FIELD_DELIMITER = ','
SKIP_HEADER = 1
FIELD_OPTIONALLY_ENCLOSED_BY = '"'
ERROR_ON_COLUMN_COUNT_MISMATCH = FALSE
REPLACE_INVALID_CHARACTERS = TRUE;| オプション | デフォルト | 説明 |
|---|---|---|
| FIELD_DELIMITER | , | フィールドの区切り文字 |
| RECORD_DELIMITER | \n | レコードの区切り文字 |
| SKIP_HEADER | 0 | スキップするヘッダー行数 |
| FIELD_OPTIONALLY_ENCLOSED_BY | NONE | フィールドの囲み文字(' または ") |
| NULL_IF | \\N | NULLとして解釈する文字列のリスト |
| ERROR_ON_COLUMN_COUNT_MISMATCH | TRUE | 列数不一致時にエラーとするか |
| ESCAPE | NONE | 囲み文字内のエスケープ文字 |
| ENCODING | UTF-8 | ファイルのエンコーディング(Shift_JIS等も指定可能) |
-- 基本的なJSON File Format
CREATE OR REPLACE FILE FORMAT util_db.formats.json_standard
TYPE = 'JSON'
STRIP_OUTER_ARRAY = TRUE
STRIP_NULL_VALUES = FALSE
IGNORE_UTF8_ERRORS = FALSE
COMPRESSION = 'AUTO';
-- ネストされたJSON(VARIANT列にロード)
CREATE OR REPLACE FILE FORMAT util_db.formats.json_nested
TYPE = 'JSON'
STRIP_OUTER_ARRAY = TRUE
ALLOW_DUPLICATE = TRUE
ENABLE_OCTAL = FALSE;| オプション | デフォルト | 説明 |
|---|---|---|
| STRIP_OUTER_ARRAY | FALSE | 外側の配列を除去して各要素を別行として扱うか |
| STRIP_NULL_VALUES | FALSE | 値がNULLのキーを除去するか |
| ALLOW_DUPLICATE | FALSE | 重複キーを許容するか |
| IGNORE_UTF8_ERRORS | FALSE | 無効なUTF-8文字を無視するか |
| DATE_FORMAT / TIME_FORMAT / TIMESTAMP_FORMAT | AUTO | 日付・時刻の解釈フォーマット |
-- Parquet File Format
CREATE OR REPLACE FILE FORMAT util_db.formats.parquet_standard
TYPE = 'PARQUET'
COMPRESSION = 'SNAPPY'
BINARY_AS_TEXT = FALSE;
-- Avro File Format
CREATE OR REPLACE FILE FORMAT util_db.formats.avro_standard
TYPE = 'AVRO'
COMPRESSION = 'AUTO';
-- ORC File Format
CREATE OR REPLACE FILE FORMAT util_db.formats.orc_standard
TYPE = 'ORC'
TRIM_SPACE = FALSE;| 特性 | CSV | JSON | Parquet | Avro | ORC |
|---|---|---|---|---|---|
| データ形式 | 行指向テキスト | 半構造化テキスト | 列指向バイナリ | 行指向バイナリ | 列指向バイナリ |
| スキーマ情報 | なし | 自己記述 | 埋め込み | 埋め込み | 埋め込み |
| 圧縮効率 | 低〜中 | 低〜中 | 高 | 中 | 高 |
| ロード速度 | 高速 | 中程度 | 高速 | 中程度 | 中程度 |
| 推奨用途 | レガシー連携 | API / IoTデータ | 分析ワークロード | Kafka連携 | Hiveからの移行 |
-- パターン1: 名前付きFile Formatを参照
COPY INTO raw_data.orders
FROM @landing_stage/orders/
FILE_FORMAT = util_db.formats.csv_standard
ON_ERROR = 'CONTINUE';
-- パターン2: インラインでオプションを指定
COPY INTO raw_data.events
FROM @landing_stage/events/
FILE_FORMAT = (TYPE = 'JSON' STRIP_OUTER_ARRAY = TRUE);
-- パターン3: Parquetからのスキーマ自動検出ロード
COPY INTO raw_data.metrics
FROM @landing_stage/metrics/
FILE_FORMAT = util_db.formats.parquet_standard
MATCH_BY_COLUMN_NAME = CASE_INSENSITIVE;
-- アンロード: テーブルからParquetファイルに出力
COPY INTO @export_stage/reports/
FROM analytics.monthly_report
FILE_FORMAT = util_db.formats.parquet_standard
HEADER = TRUE
OVERWRITE = TRUE;-- ステージ作成時にFile Formatを指定
CREATE OR REPLACE STAGE csv_landing
URL = 's3://my-bucket/csv/'
STORAGE_INTEGRATION = s3_integration
FILE_FORMAT = util_db.formats.csv_standard;
-- この場合COPY INTOでFILE_FORMATの指定が不要
COPY INTO raw_data.orders FROM @csv_landing;-- 一覧表示
SHOW FILE FORMATS IN SCHEMA util_db.formats;
-- 定義の詳細確認
DESCRIBE FILE FORMAT util_db.formats.csv_standard;
-- オプションの変更
ALTER FILE FORMAT util_db.formats.csv_standard
SET SKIP_HEADER = 2;
-- 削除
DROP FILE FORMAT util_db.formats.csv_standard;| エラー | 原因 | 対処 |
|---|---|---|
| Number of columns mismatch | CSVの列数とテーブル定義の列数が不一致 | ERROR_ON_COLUMN_COUNT_MISMATCH = FALSEにするか、テーブル定義を修正 |
| Invalid UTF-8 character | Shift_JIS等の非UTF-8ファイル | ENCODING = 'SHIFT_JIS'を指定、またはREPLACE_INVALID_CHARACTERS = TRUE |
| Failed to parse JSON | JSONの構文エラーまたは外側配列 | STRIP_OUTER_ARRAY = TRUEの設定を確認、ソースファイルの構文を検証 |
| Conversion error | データ型の変換失敗 | DATE_FORMAT / TIMESTAMP_FORMATを明示的に指定 |
Data Loading
問題 1
外部システムからS3に配置されるCSVファイルをSnowflakeにロードしている。ファイルの列数がテーブル定義より多い場合でもロードを継続したい。File Formatで設定すべきオプションはどれか。
正解: C
ERROR_ON_COLUMN_COUNT_MISMATCHをFALSEに設定すると、CSVファイルの列数がテーブル定義と一致しなくてもエラーにならず、余分な列は無視してロードが継続されます。SKIP_HEADERはヘッダー行のスキップ、ON_ERRORは個別の行エラーの処理方法、REPLACE_INVALID_CHARACTERSは無効文字の置換であり、列数不一致には対応しません。
COPY INTOでFile Formatを指定する方法は何通りありますか?
3通りあります。(1) 名前付きFile Formatを事前に作成してFILE_FORMAT = my_formatで参照する方法、(2) COPY INTO文内でFILE_FORMAT = (TYPE = 'CSV' FIELD_DELIMITER = '|')のようにインラインで指定する方法、(3) ステージに紐付けたFile Formatを使用する方法です。再利用性の観点から名前付きFile Formatの作成が推奨されます。
Parquet形式でSTRIPE_COUNTやROW_GROUP_SIZEを指定できますか?
Snowflakeの COPY INTO <location>(アンロード)では、COPY INTO ... FILE_FORMAT = (TYPE = 'PARQUET')で出力可能ですが、ROW_GROUP_SIZEなどのParquet固有の物理レイアウトパラメータは直接指定できません。Snowflakeはアンロード時にデフォルトの最適値を使用します。厳密なParquet物理設定が必要な場合は、外部ツール(Spark等)でのアンロードを検討してください。
File FormatはスキーマをまたいでCOPY INTOで参照できますか?
はい、完全修飾名(database.schema.format_name)で指定すれば、異なるスキーマやデータベースのFile Formatを参照できます。ただし、参照元のロールにFile Formatに対するUSAGE権限が必要です。共通のFile Formatを中央管理スキーマ(例: util_db.formats)にまとめて管理するのが運用上のベストプラクティスです。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Snowflake資格一覧|全11試験(SnowPro)の難易度・費用
Snowflake認定資格(SnowPro)全11試験の一覧・難易度・費用・出題範囲を徹底解説。...
Snowflake試験の難易度ランキング|全11資格を徹底比較
Snowflake(SnowPro)認定全11試験の難易度をランキング形式で比較。学習時間・合格に必要なスキルから分析。...
Snowflake資格の勉強方法|効率的な学習ルートと合格のコツ
Snowflake認定資格(SnowPro)に最短で合格するための勉強方法。公式リソース・学習スケジュールを徹底ガイド。...
SnowPro Core試験完全解説|出題範囲・問題例・合格戦略
SnowPro Core Certification(COF-C03)を徹底解説。出題範囲・100問の試験形式・合格ライ...
SnowPro Platform Associate完全解説|入門試験の攻略
SnowPro Associate: Platform Certification(SOL-C01)を徹底解説。最も簡単...