Parquet Toolsをインストール

Parquet Toolsを使おうとするたびにコンパイルエラーに悩んでいる気がします。

現時点(2020/10/25)でコンパイル成功したパターンを書いておきます。

前提

  • Java 11 インストール済み
  • Maven インストール済み
$ java -version
openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)
$ mvn -version 
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /home/xxxx/maven
Java version: 11.0.2, vendor: Oracle Corporation, runtime: /home/xxxx/openjdk-11.0.2
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "5.4.0-1028-gcp", arch: "amd64", family: "unix"

ダウンロードとビルド

$ git clone https://github.com/apache/parquet-mr.git
$ cd ./parquet-mr/parquet-tools/
$ git checkout apache-parquet-1.10.1
$ mvn clean package -Plocal

apache-parquet-1.10.1 をチェックアウトしています。masterのままや最新バージョンである apache-parquet-1.11.1 では以下のようなコンパイルエラーになってしまいました。

[ERROR] parquet-mr/parquet-tools/src/main/java/org/apache/parquet/tools/command/TransCompressionCommand.java:[29,38] cannot find symbol
[ERROR]   symbol:   class CompressionConverter
[ERROR]   location: package org.apache.parquet.hadoop.util
[ERROR] parquet-mr/parquet-tools/src/main/java/org/apache/parquet/tools/command/TransCompressionCommand.java:[30,59] package org.apache.parquet.hadoop.util.CompressionConverter does not exist
[ERROR] parquet-mr/parquet-tools/src/main/java/org/apache/parquet/tools/command/DumpCommand.java:[286,27] cannot find symbol
[ERROR]   symbol:   method getCrc()
[ERROR]   location: variable pageV1 of type org.apache.parquet.column.page.DataPageV1
$ java -jar target/parquet-tools-1.10.1.jar

使ってみる

GitHubにある以下のファイルをサンプルとして利用させてもらいます。

parquet-dotnet/src/Parquet.Test/data at master · elastacloud/parquet-dotnet https://github.com/elastacloud/parquet-dotnet/tree/master/src/Parquet.Test/data

$ curl 'https://raw.githubusercontent.com/elastacloud/parquet-dotnet/master/src/Parquet.Test/data/postcodes.plain.parquet' > sample.parquet

実行例

$ java -jar target/parquet-tools-1.10.1.jar cat --json sample.parquet | less

いちいち以下の警告が表示されてしまいます。

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.apache.hadoop.security.authentication.util.KerberosUtil (file:/home/xxxx/parquet-mr/parquet-tools/target/parquet-tools-1.10.1.jar) to method sun.security.krb5.Config.getInstance()
WARNING: Please consider reporting this to the maintainers of org.apache.hadoop.security.authentication.util.KerberosUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

とりいそぎJVM--illegal-access=deny というオプションを渡せば警告は表示されなくなるようです。

$ java --illegal-access=deny -jar target/parquet-tools-1.10.1.jar cat --json sample.parquet | less

以下のような内容を parquet-tools という名前の実行権限付きのスクリプトファイルに保存しておくと楽です。

java --illegal-access=deny -jar $HOME/xxx/parquet-mr/parquet-tools/target/parquet-tools.jar "$@"

サブコマンドは以下があります。

  • cat
  • head
  • schema
  • meta
  • dump
  • merge
  • rowcount
  • size

catコマンド

Parquetファイルに含まれるデータを可読可能なフォーマットで表示します。

$ parquet-tools cat sample.parquet | less
Postcode = AB12 5BX
InUse = Yes
Latitude = 57.119458
Longitude = -2.102568
Easting = 393888
Northing = 803173
GridRef = NJ938031
District = Aberdeen City
Ward = Kincorth/Nigg/Cove
DistrictCode =  S12000033
WardCode = S13002488
Country = Scotland
CountyCode = S99999999
Constituency = Aberdeen South
Introduced = AGCWYE5LAAA7YyUA
Population = 12
Households = 6
LowerLayerSuperOutputArea = Kincorth, Leggart and Nigg South - 02
RuralOrUrban = Large urban area
Altitude = 56
LSOACode = S01006609

Postcode = AB3 2HQ
InUse = No
Latitude = 56.964593
...

--json をつければJSONLのフォーマットになります。

$ parquet-tools cat --json sample.parquet | less
{"Postcode":"AB12 5BX","InUse":"Yes","Latitude":57.119458,"Longitude":-2.102568,"Easting":393888,"Northing":803173,"GridRef":"NJ938031","District":"Aberdeen City","Ward":"Kincorth/Nigg/Cove","DistrictCode":" S12000033","WardCode":"S13002488","Country":"Scotland","CountyCode":"S99999999","Constituency":"Aberdeen South","Introduced":"AGCWYE5LAAA7YyUA","Population":12,"Households":6,"LowerLayerSuperOutputArea":"Kincorth, Leggart and Nigg South - 02","RuralOrUrban":"Large urban area","Altitude":56,"LSOACode":"S01006609"}
{"Postcode":"AB3 2HQ",...

2020/10/28 追記

catコマンドでの値の表示はあまり正確ではなさそうです。以下の記事に書きました。

headコマンド

catコマンドと同じフォーマットで先頭の5レコードを表示します。

$ parquet-tools head sample.parquet

schemaコマンド

スキーマを表示します。

$ parquet-tools schema sample.parquet       
message spark_schema {
  optional binary Postcode (UTF8);
  optional binary InUse (UTF8);
  optional double Latitude;
  optional double Longitude;
  optional int32 Easting;
  optional int32 Northing;
  optional binary GridRef (UTF8);
  optional binary County (UTF8);
  optional binary District (UTF8);
  optional binary Ward (UTF8);
  optional binary DistrictCode (UTF8);
  optional binary WardCode (UTF8);
  optional binary Country (UTF8);
  optional binary CountyCode (UTF8);
  optional binary Constituency (UTF8);
  optional int96 Introduced;
  optional int96 Terminated;
  optional binary Parish (UTF8);
  optional binary NationalPark (UTF8);
  optional int32 Population;
  optional int32 Households;
  optional binary BuiltUpArea (UTF8);
  optional binary BuiltUpSubDivision (UTF8);
  optional binary LowerLayerSuperOutputArea (UTF8);
  optional binary RuralOrUrban (UTF8);
  optional binary Region (UTF8);
  optional int32 Altitude;
  optional int32 LondonZone;
  optional binary LSOACode (UTF8);
}

metaコマンド

データ型や統計情報などのメタ情報を表示します。

$ parquet-tools meta sample.parquet
file:                      file:/home/xxxx/sample.parquet
creator:                   parquet-mr version 1.8.1 (build 4aba4dae7bb0d4edbcf7923ae1339f28fd3f7fcf)
extra:                     org.apache.spark.sql.parquet.row.metadata = {"type":"struct","fields":[{"name":"Postcode","type":"string","nullable":true,"metadata":{}},{"name":"InUse","type":"string","nullable":true,"metadata":{}},{"name":...
                                                                                
file schema:               spark_schema
--------------------------------------------------------------------------------
Postcode:                  OPTIONAL BINARY O:UTF8 R:0 D:1
InUse:                     OPTIONAL BINARY O:UTF8 R:0 D:1
Latitude:                  OPTIONAL DOUBLE R:0 D:1
...

row group 1:               RC:237 TS:47513 OFFSET:4
--------------------------------------------------------------------------------
Postcode:                   BINARY UNCOMPRESSED DO:0 FPO:4 SZ:2742/2742/1.00 VC:237 ENC:BIT_PACKED,PLAIN,RLE ST:[no stats for this column]
InUse:                      BINARY UNCOMPRESSED DO:0 FPO:2746 SZ:101/101/1.00 VC:237 ENC:PLAIN_DICTIONARY,BIT_PACKED,RLE ST:[no stats for this column]
Latitude:                   DOUBLE UNCOMPRESSED DO:0 FPO:2847 SZ:1947/1947/1.00 VC:237 ENC:BIT_PACKED,PLAIN,RLE ST:[min: 49.9957, max: 58.592488, num_nulls: 0]
...

dumpコマンド

データとメタ情報を出力します。データはレコードごとではなくカラムごとです。

$ parquet-tools dump sample.parquet

mergeコマンド

複数のParquetファイルを結合し、1つのParquetファイルを出力します。

rowcountコマンド

レコード数を表示します。

$ parquet-tools rowcount sample.parquet       
Total RowCount: 237

sizeコマンド

データの大きさを表示します。ファイルサイズとは違うようです。

$ parquet-tools size sample.parquet    
Total Size: 47513 bytes