Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Primeiros passos com chDB

Neste guia, vamos começar a usar a versão para Python do chDB. Vamos começar consultando um arquivo JSON no S3 e, em seguida, criar uma tabela no chDB com base nesse arquivo e fazer algumas consultas nos dados. Também veremos como fazer com que as consultas retornem dados em diferentes formatos, incluindo Apache Arrow e Pandas, e, por fim, aprenderemos a consultar DataFrames do pandas.

Configuração

Primeiro, vamos criar um ambiente virtual:

python -m venv .venv
source .venv/bin/activate

E agora vamos instalar o chDB. Certifique-se de que você esteja usando a versão 2.0.3 ou superior:

pip install "chdb>=2.0.2"

E agora, vamos instalar o ipython:

pip install ipython

Vamos usar o ipython para executar os comandos no restante do guia, que pode ser iniciado com:

ipython

Também vamos usar Pandas e Apache Arrow neste guia, então vamos instalar essas bibliotecas também:

pip install pandas pyarrow

Consultando um arquivo JSON no S3

Agora, vamos ver como consultar um arquivo JSON armazenado em um bucket do S3. O dataset de dislikes do YouTube contém mais de 4 bilhões de linhas de dislikes em vídeos do YouTube até 2021. Vamos trabalhar com um dos arquivos JSON desse dataset.

Importe o chDB:

import chdb

Podemos escrever a seguinte consulta para descrever a estrutura de um dos arquivos 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)"

Também podemos contar o total de linhas nesse arquivo:

chdb.query(
  """
  SELECT count()
  FROM s3(
    's3://clickhouse-public-datasets/youtube/original/files/' ||
    'youtubedislikes_20211127161229_18654868.1637897329_vid.json.zst',
    'JSONLines'
  )"""
)
336432

Este arquivo contém pouco mais de 300.000 registros.

O chDB ainda não oferece suporte a receber parâmetros de consulta, mas podemos extrair o caminho e passá-lo via 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')
  """
)

Configurando o formato de saída

O formato de saída padrão é CSV, mas podemos alterá-lo por meio do parâmetro output_format. O chDB oferece suporte aos formatos de dados do ClickHouse, bem como a alguns formatos próprios, incluindo DataFrame, que retorna um DataFrame do pandas:

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

Ou, se quisermos recuperar uma tabela Arrow do Apache:

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]]

Criando uma tabela a partir de um arquivo JSON

Em seguida, vamos ver como criar uma tabela no chDB. Precisamos usar uma API diferente para isso, então primeiro vamos importá-la:

from chdb import session as chs

Em seguida, vamos inicializar uma sessão. Se quisermos que a sessão seja persistida em disco, precisaremos fornecer um nome de diretório. Se deixarmos em branco, a sessão será temporária: o chDB manterá os dados em um diretório temporário em disco e os excluirá quando a sessão for encerrada, portanto, os dados não persistirão.

sess = chs.Session("gettingStarted.chdb")

Em seguida, vamos criar um banco de dados:

sess.query("CREATE DATABASE IF NOT EXISTS youtube")

Agora podemos criar uma tabela dislikes com base no schema do arquivo JSON, usando a técnica CREATE...EMPTY AS. Usaremos a configuração schema_inference_make_columns_nullable para que os tipos de coluna não sejam todos convertidos em 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
  """
)

Podemos então usar a cláusula DESCRIBE para inspecionar o schema:

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"

Em seguida, vamos popular essa tabela:

sess.query(f"""
  INSERT INTO youtube.dislikes
  SELECT * 
  FROM s3('{path}','JSONLines')
  SETTINGS schema_inference_make_columns_nullable=0
  """
)

Também poderíamos fazer essas duas etapas de uma vez só, usando a técnica CREATE...AS. Vamos criar outra tabela usando essa técnica:

sess.query(f"""
  CREATE TABLE youtube.dislikes2
  ORDER BY fetch_date 
  AS 
  SELECT * 
  FROM s3('{path}','JSONLines')
  SETTINGS schema_inference_make_columns_nullable=0
  """
)

Consultando uma tabela

Por fim, vamos consultar a tabela:

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

Suponha que adicionemos uma coluna extra ao DataFrame para calcular a razão entre curtidas e dislikes. Poderíamos escrever o seguinte código:

df["likeDislikeRatio"] = df["likeCount"] / df["dislikeCount"]

Consultando um DataFrame do pandas

Podemos então consultar esse DataFrame com o chDB:

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

Você também pode ler mais sobre como consultar DataFrames do pandas no guia do desenvolvedor sobre consulta a DataFrames do pandas.

Próximos passos

Esperamos que este guia tenha oferecido uma boa visão geral do chDB. Para saber mais sobre como usá-lo, consulte os seguintes guias para desenvolvedores:

Navigation