跳至主要内容
跳至主要内容
编辑此页

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

pip install ipython

我们将使用 ipython 运行本指南其余部分中的命令,您可以通过运行以下命令来启动它

ipython

我们还将在本指南中使用 Pandas 和 Apache Arrow,所以让我们也安装这些库

pip install pandas pyarrow

查询 S3 中的 JSON 文件

现在让我们看看如何查询存储在 S3 bucket 中的 JSON 文件。 YouTube dislikes 数据集 包含截至 2021 年的 YouTube 视频超过 40 亿条点赞数据。 我们将使用该数据集中的一个 JSON 文件。

Import chdb

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'
  )"""
)
336432

该文件包含略多于 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 的良好概述。 要了解如何使用它,请参阅以下开发者指南

    © . This site is unofficial and not affiliated with ClickHouse, Inc.