Parquetのデータ型とAWS Glue Crawlerのデータ型のマッピングとAthenaからのアクセス

さまざまなデータ型を含むParquetファイルを作成し、AWS Glue Crawlerでクロールさせてみて、Data Catalogにどんなデータ型のテーブルができるかを確認しました。

結果

先に結果をまとめておきます。

左2列がParquetファイルのデータ型で、それに対して3列目がData Catalog上のデータ型、4列目がAthenaでのクエリ結果です。

Converted Type Physical Type AWS Data Catalog AWS Athena
boolean boolean boolean OK
int* / uint* int* tinyint / smallint / int / bigint OK
decimal(*) int* / binary / fix_len_byte_array decimal(*) OK
date int32 date OK
time_millis int32 timestamp 日付が勝手に付く
time_micros int64 timestamp 値が勝手に1000倍
timestamp_millis int64 timestamp OK
timestamp_micros int64 timestamp 値が勝手に1000倍
float float OK
double double OK
binary binary OK
utf8 binary string OK
fix_len_byte_array binary エラー

Parquetファイルのスキーマ

用意したParquetファイルのスキーマは次のようになっています。

message m {
  required boolean col_b1;
  required int32 col_i32;
  required int32 col_i32_int8 (INT_8);
  required int32 col_i32_int16 (INT_16);
  required int32 col_i32_int32 (INT_32);
  required int32 col_i32_uint8 (UINT_8);
  required int32 col_i32_uint16 (UINT_16);
  required int32 col_i32_uint32 (UINT_32);
  required int64 col_i64;
  required int64 col_i64_int64 (INT_64);
  required int64 col_i64_uint64 (UINT_64);
  required int32 col_i32_dec10 (DECIMAL(1,0));
  required int32 col_i32_dec31 (DECIMAL(3,1));
  required int32 col_i32_dec94 (DECIMAL(9,4));
  required int64 col_i64_dec188 (DECIMAL(18,8));
  required binary col_bin_dec42 (DECIMAL(4,2));
  required fixed_len_byte_array(2) col_fixed_dec42 (DECIMAL(4,2));
  required int32 col_i32_date (DATE);
  required int32 col_i32_timemillis (TIME_MILLIS);
  required int64 col_i64_timemicros (TIME_MICROS);
  required int64 col_i64_timestampmillis (TIMESTAMP_MILLIS);
  required int64 col_i64_timestampmicros (TIMESTAMP_MICROS);
  required float col_f32;
  required double col_f64;
  required binary col_bin;
  required binary col_bin_utf8 (UTF8);
  required fixed_len_byte_array(3) col_fixed;
}

以下の記事で作成したParquetファイルです。

Glue Crawlerの結果

ParquetファイルをS3に置いて、AWS Glue Crawlerでクロールさせたところ、Data Catalogには以下のようなスキーマのテーブルが作成されました。

f:id:suzuki-navi:20201101161712p:plain

Athenaから参照

AWS AthenaからこのData Catalogのテーブルにアクセスしてみました。

SELECT * FROM "example"."test1";

以下のようなエラーメッセージになりました。

HIVE_CURSOR_ERROR: Can not read value at 0 in block 0 in file s3://xxxx/xxxx/output.parquet

SELECT *ではなく特定のカラムにアクセスすると正常に結果を返せることが多く、エラーになる規則性がわかりませんでした。

カラムを限定してSELECTすると結果は最初に掲げた表のとおりです。boolean、整数、decimal、浮動小数点数、stringのカラムは正しい結果が返されました。decimalは物理型が整数でもバイナリでも大丈夫でした。

日時のデータ型に関しては結果が怪しいです。Data Catalog上でtimestamp型となってしまう4カラムはAthenaからはデータ型を区別できないと考えるとつじつまがあいます。4カラムともtimestamp_millisと解釈しているようです。

SELECT col_i32_date, col_i32_timemillis, col_i64_timemicros, col_i64_timestampmillis, col_i64_timestampmicros FROM "example"."test1";

f:id:suzuki-navi:20201101161141p:plain

固定長バイナリ(fix_len_byte_array)は以下のようなエラーになりました。

NOT_SUPPORTED: Parquet type FIXED_LEN_BYTE_ARRAY supported as DECIMAL; got null

可変長バイナリ(binary)は大丈夫。バイナリを直接確認できるようです。

SELECT  col_bin FROM "example"."test1";

f:id:suzuki-navi:20201101161201p:plain