0xf

日記だよ

Parquetファイルのスキーマを参照する(謎の key_value フィールド編)

ちょっと Parquet ファイルのスキーマを確認したいことがあった。

こんな感じのスクリプトを書いた。

import argparse
import pyarrow.parquet as pq
from pyarrow.parquet import ParquetFile


def main(input_file: str) -> None:
    try:
        parquet_file: ParquetFile = pq.ParquetFile(input_file)
        schema = parquet_file.schema
        print(schema)
    except FileNotFoundError:
        print(f"Error: File not found - {input_file}")
    except Exception as e:
        print(f"An error occurred: {e}")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Print Parquet file's schema")
    parser.add_argument("input_file", help="Path to the parquet file")
    args = parser.parse_args()
    main(args.input_file)

こいつで確認したら、map<string, string> なカラムは以下のような感じになってた。resource_tags は、いわゆるタグが複数格納されている感じね。

resource_tags: map<string, string ('resource_tags')>
  child 0, resource_tags: struct<key: string not null, value: string> not null
      child 0, key: string not null
      child 1, value: string

mapは struct<key: string not null, value: string> が複数格納されている。

なんかネストされた構造がある? と思ってフォーマットの説明を眺めていた。

MAP is used to annotate types that should be interpreted as a map from keys to values. MAP must annotate a 3-level structure:

<map-repetition> group (MAP) { repeated group key_value { required <key-type> key; <value-repetition> <value-type> value; } }

  • The outer-most level must be a group annotated with MAP that contains a single field named key_value. The repetition of this level must be either optional or required and determines whether the map is nullable.
  • The middle level, named key_value, must be a repeated group with a key field for map keys and, optionally, a value field for map values. It must not contain any other values.

map<string, T> は、

  • key_valueって名前のフィールドを持つ struct だよ
  • key_valuekey: string (required)と、value: T(optional)を持つ structrepeatedになっているよ

というように表現される。なるほどね。

BigQuery にデータをインポートしたとき、map<string, T>struct<{key_value: Repeated<strict{key: string, value: T}>}>みたいな感じに変換されていて、key_valueってどっからきたんやろと思っていた。Parquetファイルの方の仕様だったのねえ。