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/activateE 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 ipythonVamos usar o ipython para executar os comandos no restante do guia, que pode ser iniciado com:
ipythonTambém vamos usar Pandas e Apache Arrow neste guia, então vamos instalar essas bibliotecas também:
pip install pandas pyarrowConsultando 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 chdbPodemos 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'
)"""
)336432Este 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 35307Ou, 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 chsEm 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 49489Suponha 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.051021Você 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: