このガイドでは、Python 版の chDB を使って、すぐに使い始めるための手順を説明します。
まず S3 上の JSON ファイルに対してクエリを実行し、その JSON ファイルを元に chDB 内にテーブルを作成し、データに対していくつかクエリを実行します。
また、Apache Arrow や Pandas など、複数のフォーマットでクエリ結果を取得する方法を確認し、最後に Pandas の DataFrame をクエリする方法を学びます。
セットアップ
まずは仮想環境を作成します。
python -m venv .venv
source .venv/bin/activate
次に、chDB をインストールします。
バージョン 2.0.3 以降であることを確認してください。
pip install "chdb>=2.0.2"
では次に、IPython をインストールします。
このガイドの以降の手順では、ipython を使ってコマンドを実行します。次のコマンドを実行して ipython を起動します。
このガイドでは Pandas と Apache Arrow も使用するので、これらのライブラリもインストールしておきましょう。
pip install pandas pyarrow
S3 内の JSON ファイルをクエリする
ここでは、S3 バケットに保存されている JSON ファイルをどのようにクエリするかを見ていきます。
YouTube dislikes dataset には、2021 年までの YouTube 動画に対する 40 億行以上の低評価データが含まれています。
このデータセットに含まれる JSON ファイルの 1 つを使って進めます。
chdb をインポートします:
次のクエリで、ある JSON ファイルの構造を確認できます。
chdb.query(
"""
DESCRIBE s3(
's3://clickhouse-public-datasets/youtube/original/files/' ||
'youtubedislikes_20211127161229_18654868.1637897329_vid.json.zst',
'JSONLines'
)
SETTINGS describe_compact_output=1
"""
)
"id","Nullable(String)"
"fetch_date","Nullable(String)"
"upload_date","Nullable(String)"
"title","Nullable(String)"
"uploader_id","Nullable(String)"
"uploader","Nullable(String)"
"uploader_sub_count","Nullable(Int64)"
"is_age_limit","Nullable(Bool)"
"view_count","Nullable(Int64)"
"like_count","Nullable(Int64)"
"dislike_count","Nullable(Int64)"
"is_crawlable","Nullable(Bool)"
"is_live_content","Nullable(Bool)"
"has_subtitles","Nullable(Bool)"
"is_ads_enabled","Nullable(Bool)"
"is_comments_enabled","Nullable(Bool)"
"description","Nullable(String)"
"rich_metadata","Array(Tuple(
call Nullable(String),
content Nullable(String),
subtitle Nullable(String),
title Nullable(String),
url Nullable(String)))"
"super_titles","Array(Tuple(
text Nullable(String),
url Nullable(String)))"
"uploader_badges","Nullable(String)"
"video_badges","Nullable(String)"
また、そのファイルの行数を数えることもできます:
chdb.query(
"""
SELECT count()
FROM s3(
's3://clickhouse-public-datasets/youtube/original/files/' ||
'youtubedislikes_20211127161229_18654868.1637897329_vid.json.zst',
'JSONLines'
)"""
)
このファイルには 30 万件強のレコードが含まれています。
chdb はまだクエリパラメータの受け渡しをサポートしていませんが、パスを取り出して f 文字列で渡すことができます。
path = 's3://clickhouse-public-datasets/youtube/original/files/youtubedislikes_20211127161229_18654868.1637897329_vid.json.zst'
chdb.query(
f"""
SELECT count()
FROM s3('{path}','JSONLines')
"""
)
注記
これはプログラム内で定義した変数に対して行う分には問題ありませんが、ユーザーからの入力に対しては決して行わないでください。そうしないと、クエリが SQL インジェクション攻撃に対して無防備になります。
デフォルトの出力フォーマットは CSV ですが、output_format パラメータで変更できます。
chDB は ClickHouse のデータフォーマットに加えて、DataFrame を含む独自のフォーマットもサポートしており、DataFrame フォーマットでは Pandas DataFrame が返されます。
result = chdb.query(
f"""
SELECT is_ads_enabled, count()
FROM s3('{path}','JSONLines')
GROUP BY ALL
""",
output_format="DataFrame"
)
print(type(result))
print(result)
<class 'pandas.core.frame.DataFrame'>
is_ads_enabled count()
0 False 301125
1 True 35307
また、結果を Apache Arrow のテーブルとして取得したい場合は次のようにします。
result = chdb.query(
f"""
SELECT is_live_content, count()
FROM s3('{path}','JSONLines')
GROUP BY ALL
""",
output_format="ArrowTable"
)
print(type(result))
print(result)
<class 'pyarrow.lib.Table'>
pyarrow.Table
is_live_content: bool
count(): uint64 not null
----
is_live_content: [[false,true]]
count(): [[315746,20686]]
JSON ファイルからテーブルを作成する
次に、chDB でテーブルを作成する方法を見ていきます。
これを行うには別の API を利用する必要があるので、まずはそれをインポートします。
from chdb import session as chs
次にセッションを初期化します。
セッションをディスク上に永続化したい場合は、ディレクトリ名を指定する必要があります。
何も指定しない場合、データベースはメモリ上だけに保持され、Python プロセスを終了した時点で失われます。
sess = chs.Session("gettingStarted.chdb")
次にデータベースを作成します。
sess.query("CREATE DATABASE IF NOT EXISTS youtube")
これで、JSON ファイルのスキーマに基づいて CREATE...EMPTY AS 手法を使い、dislikes テーブルを作成できます。
すべてのカラム型が Nullable になってしまわないようにするため、schema_inference_make_columns_nullable 設定を使用します。
sess.query(f"""
CREATE TABLE youtube.dislikes
ORDER BY fetch_date
EMPTY AS
SELECT *
FROM s3('{path}','JSONLines')
SETTINGS schema_inference_make_columns_nullable=0
"""
)
次に、DESCRIBE 句を使用してスキーマを確認します。
sess.query(f"""
DESCRIBE youtube.dislikes
SETTINGS describe_compact_output=1
"""
)
"id","String"
"fetch_date","String"
"upload_date","String"
"title","String"
"uploader_id","String"
"uploader","String"
"uploader_sub_count","Int64"
"is_age_limit","Bool"
"view_count","Int64"
"like_count","Int64"
"dislike_count","Int64"
"is_crawlable","Bool"
"is_live_content","Bool"
"has_subtitles","Bool"
"is_ads_enabled","Bool"
"is_comments_enabled","Bool"
"description","String"
"rich_metadata","Array(Tuple(
call String,
content String,
subtitle String,
title String,
url String))"
"super_titles","Array(Tuple(
text String,
url String))"
"uploader_badges","String"
"video_badges","String"
次に、そのテーブルにデータを投入します。
sess.query(f"""
INSERT INTO youtube.dislikes
SELECT *
FROM s3('{path}','JSONLines')
SETTINGS schema_inference_make_columns_nullable=0
"""
)
CREATE...AS 手法を使えば、これら両方の手順を一度にまとめて実行することもできます。
では、その手法を使って別のテーブルを作成してみましょう。
sess.query(f"""
CREATE TABLE youtube.dislikes2
ORDER BY fetch_date
AS
SELECT *
FROM s3('{path}','JSONLines')
SETTINGS schema_inference_make_columns_nullable=0
"""
)
テーブルをクエリする
最後に、そのテーブルに対してクエリを実行してみましょう。
df = sess.query("""
SELECT uploader, sum(view_count) AS viewCount, sum(like_count) AS likeCount, sum(dislike_count) AS dislikeCount
FROM youtube.dislikes
GROUP BY ALL
ORDER BY viewCount DESC
LIMIT 10
""",
"DataFrame"
)
df
アップローダー 視聴回数 高評価数 低評価数
0 Jeremih 139066569 812602 37842
1 TheKillersMusic 109313116 529361 11931
2 LetsGoMartin- Canciones Infantiles 104747788 236615 141467
3 Xiaoying Cuisine 54458335 1031525 37049
4 Adri 47404537 279033 36583
5 Diana and Roma IND 43829341 182334 148740
6 ChuChuTV Tamil 39244854 244614 213772
7 Cheez-It 35342270 108 27
8 Anime Uz 33375618 1270673 60013
9 RC Cars OFF Road 31952962 101503 49489
次に、DataFrame に「高評価と低評価の比率」を計算するための列を追加するとします。
その場合、次のようなコードを記述できます。
df["likeDislikeRatio"] = df["likeCount"] / df["dislikeCount"]
Pandas データフレームをクエリする
その後、chDB からその DataFrame に対してクエリを実行できます。
chdb.query(
"""
SELECT uploader, likeDislikeRatio
FROM Python(df)
""",
output_format="DataFrame"
)
uploader likeDislikeRatio
0 Jeremih 21.473548
1 TheKillersMusic 44.368536
2 LetsGoMartin- Canciones Infantiles 1.672581
3 Xiaoying Cuisine 27.842182
4 Adri 7.627395
5 Diana and Roma IND 1.225857
6 ChuChuTV Tamil 1.144275
7 Cheez-It 4.000000
8 Anime Uz 21.173296
9 RC Cars OFF Road 2.051021
Pandas の DataFrame に対するクエリについては、Querying Pandas developer guide も参照してください。
次のステップ
このガイドを通じて、chDB の概要を把握していただけたかと思います。
さらに詳しい使い方については、以下の開発者向けガイドを参照してください。