Apache Parquet の Logical Types に関するメモ
去年末になりますが、 embulk-output-s3_parquet
という Embulk Plugin にて Logical Type をサポートするためのパッチを書き、マージしていただきました。
個人的な主な目的は timestamp 型をサポートすることでした。 Athena や BigQuery から参照するにあたり timestamp 型として扱えるか否かで使い勝手は大きく変わります。 Logical Type としての扱いを期待するかを設定に書く必要はあるものの、割と簡素な設定で timestamp 型対応ができるようになったのではないかと思います。
さてこの Logical Type ですが、 2020 年 2 月現在 2 種類の仕様が混在してかつ古い仕様が事実上スタンダードになっている状態です。 自分は最初混乱したのですが、この不幸の連鎖を止めたいので、本記事に自分が把握した状態を記録しておきます。
古い仕様 "Converted Types"
ここまで一口に "Logical Types" といってしまったのですが、ドキュメント上は古い仕様は Converted Types
, 新しい仕様が Logical Types
と区別されます。
そして現在使われる Logical Types としてはこの Converted Types が一般的でしょう。
前提として、 Parquet がサポートする型 は以下のものになります。
- BOOLEAN
- INT32
- INT64
- INT96
- FLOAT
- DOUBLE
- BYTE_ARRAY
Converted Types ではこれらの型に別解釈を与えることができます。 これは OriginalType に定義されています。 (このクラス名からか、 JIRA や GitHub 上のやり取りを見ると Converted Types のことを Original Types と呼ぶこともあるっぽい?ようです。 Java 実装に限った話かも)
- MAP,
- LIST,
- UTF8,
- MAP_KEY_VALUE,
- ENUM,
- DECIMAL,
- DATE,
- TIME_MILLIS,
- TIME_MICROS,
- TIMESTAMP_MILLIS,
- TIMESTAMP_MICROS,
- UINT_8,
- UINT_16,
- UINT_32,
- UINT_64,
- INT_8,
- INT_16,
- INT_32,
- INT_64,
- JSON,
- BSON,
- INTERVAL
embulk-output-s3_parquet
でサポートする timestamp 型はここに現れる TIMESTAMP_MILLIS
, TIMESTAMP_MICROS
になります!
また Parquet では文字列型がこの Converted Types
の UTF8
OriginalType を使って表現されます。
そのため、Parquet の Converted Types は例えば Avro における Logical Types よりは多くのユーザが触れる機会がある概念かも知れません。
新しい仕様 "Logical Types"
新しい Logical Types は UUID やナノ秒精度 timestamp などさらにリッチな型をサポートしていたり、 Builder パターンでのスキーマ構築をサポートしていたりと様々な更新を含みます。 Converted Types との互換性も考慮されており、互換がある表現の場合は変換メソッドも提供されます。
これは Parquet 1.11.0 からサポートされているのですが、 maven central repository に上がったのが 2019 年 11 月でありまだ歴史が浅い機能といえます。 ミドルウェアの対応としても、 Hive でサポート開始がされ始めた ようですが Spark はまだ だったり普及するのにはまだ時間を要しそうです。 BigQuery などクラウドサービスにおいても、スケジュールは定かではないですが、サポートするにしてももうしばらく時間が必要かも知れません。
そんな訳で 2020 年 2 月現在、まだ多くの場合は Converted Types を利用することになると思うのですが、将来的に Logical Types に置き換えることや変換メソッドがあることを知っておくと良いでしょう。 またドキュメントは新しい Logical Types に関する記述の方が増えていくと思われ、現行2つの仕様がありドキュメントの記述と自分が必要としてい仕様がどちらのものか意識することがしばらく必要かも知れません。