Getting started with chDB
在本指南中,我们将开始使用 chDB 的 Python 版本。 我们将从查询 S3 上的 JSON 文件开始,然后基于 JSON 文件在 chDB 中创建一个表,并对数据进行一些查询。 我们还将了解如何让查询以不同的格式返回数据,包括 Apache Arrow 和 Panda,最后我们将学习如何查询 Pandas DataFrames。
让我们首先创建一个虚拟环境
python -m venv .venv
source .venv/bin/activate
现在我们将安装 chDB。 确保您拥有 2.0.3 或更高版本
pip install "chdb>=2.0.2"
现在我们将安装 ipython
我们将使用 ipython 运行本指南其余部分中的命令,您可以通过运行以下命令来启动它
我们还将在本指南中使用 Pandas 和 Apache Arrow,所以让我们也安装这些库
pip install pandas pyarrow
查询 S3 中的 JSON 文件
现在让我们看看如何查询存储在 S3 bucket 中的 JSON 文件。 YouTube dislikes 数据集 包含截至 2021 年的 YouTube 视频超过 40 亿条点赞数据。 我们将使用该数据集中的一个 JSON 文件。
Import 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'
)"""
)
该文件包含略多于 300,000 条记录。
chdb 尚未支持传入查询参数,但我们可以提取路径并通过 f-String 传入。
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,它返回一个 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 文件中的模式创建一个 dislikes 表,使用 CREATE...EMPTY AS 技术。 我们将使用 schema_inference_make_columns_nullable 设置,以便所有列类型都不会被设为 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
uploader viewCount likeCount dislikeCount
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 dataframe
然后我们可以从 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
您还可以阅读更多关于在 Querying Pandas 开发者指南 中查询 Pandas DataFrames 的信息。
后续步骤
希望本指南能为您提供有关 chDB 的良好概述。 要了解如何使用它,请参阅以下开发者指南