Parquetはデータを列指向で効率的に保存するためのファイルフォーマットです。
ClickHouseはParquetファイルの読み書きをサポートしています。
ヒント
クエリ内でファイルパスを参照する際、ClickHouseが読み取ろうとする場所は、使用しているClickHouseのバリアントによって異なります。
clickhouse-localを使用している場合、ClickHouse Localを起動した場所に相対する場所から読み取ります。
ClickHouse Serverまたはclickhouse client経由でClickHouse Cloudを使用している場合、サーバーの/var/lib/clickhouse/user_files/ディレクトリに相対する場所から読み取ります。
 
Parquetからのインポート
データをロードする前に、file()関数を使用して例のParquetファイルの構造を探ることができます:
DESCRIBE TABLE file('data.parquet', Parquet);
 
第二引数にParquetを指定したので、ClickHouseはファイルフォーマットを認識します。これにより、カラムとそのタイプが出力されます:
┌─name─┬─type─────────────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐
│ path │ Nullable(String) │              │                    │         │                  │                │
│ date │ Nullable(String) │              │                    │         │                  │                │
│ hits │ Nullable(Int64)  │              │                    │         │                  │                │
└──────┴──────────────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘
 
実際にデータをインポートする前に、SQLの力を使ってファイルを探ることもできます:
SELECT *
FROM file('data.parquet', Parquet)
LIMIT 3;
 
┌─path──────────────────────┬─date───────┬─hits─┐
│ Akiba_Hebrew_Academy      │ 2017-08-01 │  241 │
│ Aegithina_tiphia          │ 2018-02-01 │   34 │
│ 1971-72_Utah_Stars_season │ 2016-10-01 │    1 │
└───────────────────────────┴────────────┴──────┘
 
ヒント
file()やINFILE/OUTFILEの明示的なフォーマット指定を省略することができます。
その場合、ClickHouseはファイル拡張子に基づいてフォーマットを自動的に検出します。
 
既存テーブルへのインポート
Parquetデータをインポートするテーブルを作成しましょう:
CREATE TABLE sometable
(
    `path` String,
    `date` Date,
    `hits` UInt32
)
ENGINE = MergeTree
ORDER BY (date, path);
 
これで、FROM INFILE句を使用してデータをインポートできます:
INSERT INTO sometable
FROM INFILE 'data.parquet' FORMAT Parquet;
SELECT *
FROM sometable
LIMIT 5;
 
┌─path──────────────────────────┬───────date─┬─hits─┐
│ 1988_in_philosophy            │ 2015-05-01 │   70 │
│ 2004_Green_Bay_Packers_season │ 2015-05-01 │  970 │
│ 24_hours_of_lemans            │ 2015-05-01 │   37 │
│ 25604_Karlin                  │ 2015-05-01 │   20 │
│ ASCII_ART                     │ 2015-05-01 │    9 │
└───────────────────────────────┴────────────┴──────┘
 
ClickHouseがParquetの文字列(dateカラム内)をDate型に自動的に変換したことに注目してください。これは、ClickHouseがターゲットテーブルの型に基づいて自動的に型キャストを行うためです。
ローカルファイルをリモートサーバーに挿入する
ローカルのParquetファイルをリモートのClickHouseサーバーに挿入したい場合は、ファイルの内容をclickhouse-clientにパイプすることで実行できます。以下のようにします:
clickhouse client -q "INSERT INTO sometable FORMAT Parquet" < data.parquet
 
Parquetファイルから新しいテーブルを作成する
ClickHouseはParquetファイルのスキーマを読み取るため、テーブルを即座に作成することができます:
CREATE TABLE imported_from_parquet
ENGINE = MergeTree
ORDER BY tuple() AS
SELECT *
FROM file('data.parquet', Parquet)
 
これにより、指定したParquetファイルから自動的にテーブルが作成され、データが入力されます:
DESCRIBE TABLE imported_from_parquet;
 
┌─name─┬─type─────────────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐
│ path │ Nullable(String) │              │                    │         │                  │                │
│ date │ Nullable(String) │              │                    │         │                  │                │
│ hits │ Nullable(Int64)  │              │                    │         │                  │                │
└──────┴──────────────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘
 
デフォルトでは、ClickHouseはカラム名、型、および値に対して厳格です。しかし、時にはインポート中に存在しないカラムやサポートされていない値を省略することができます。これはParquet設定で管理できます。
ヒント
ClickHouse CloudでINTO OUTFILEを使用する場合、ファイルが書き込まれるマシンのclickhouse clientでコマンドを実行する必要があります。
 
任意のテーブルまたはクエリ結果をParquetファイルにエクスポートするには、INTO OUTFILE句を使用します:
SELECT *
FROM sometable
INTO OUTFILE 'export.parquet'
FORMAT Parquet
 
これにより、作業ディレクトリにexport.parquetファイルが作成されます。
ClickHouseとParquetデータ型
ClickHouseとParquetのデータ型はほとんど同一ですが、少し異なる点もあります。例えば、ClickHouseはDateTime型をParquetのint64としてエクスポートします。その後、再度ClickHouseにインポートすると、数値が表示されます(time.parquetファイル):
SELECT * FROM file('time.parquet', Parquet);
 
┌─n─┬───────time─┐
│ 0 │ 1673622611 │
│ 1 │ 1673622610 │
│ 2 │ 1673622609 │
│ 3 │ 1673622608 │
│ 4 │ 1673622607 │
└───┴────────────┘
 
この場合、型変換を使用できます:
SELECT
    n,
    toDateTime(time)                 <--- int to time
FROM file('time.parquet', Parquet);
 
┌─n─┬────toDateTime(time)─┐
│ 0 │ 2023-01-13 15:10:11 │
│ 1 │ 2023-01-13 15:10:10 │
│ 2 │ 2023-01-13 15:10:09 │
│ 3 │ 2023-01-13 15:10:08 │
│ 4 │ 2023-01-13 15:10:07 │
└───┴─────────────────────┘
 
さらなる読書
ClickHouseは、多くのフォーマットをサポートしており、さまざまなシナリオやプラットフォームをカバーしています。次の資料で、さらに多くのフォーマットやそれらの操作方法を探ってみてください:
また、clickhouse-localをチェックしてください。これは、Clickhouseサーバーがなくてもローカル/リモートファイルで作業できる完全機能のポータブルツールです。