Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Prise en main de chDB

Dans ce guide, nous allons prendre en main la version Python de chDB. Nous commencerons par interroger un fichier JSON sur S3, puis nous créerons une table dans chDB à partir de ce fichier avant d'exécuter quelques requêtes sur les données. Nous verrons également comment renvoyer des données dans différents formats, notamment Apache Arrow et Pandas, puis nous apprendrons enfin à interroger des DataFrame Pandas.

Préparation

Commençons par créer un environnement virtuel :

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

Et maintenant, nous allons installer chDB. Assurez-vous d’utiliser la version 2.0.3 ou une version ultérieure :

pip install "chdb>=2.0.2"

Nous allons maintenant installer ipython :

pip install ipython

Nous allons utiliser ipython pour exécuter les commandes dans la suite de ce guide, que vous pouvez lancer avec la commande suivante :

ipython

Nous utiliserons aussi Pandas et Apache Arrow dans ce guide, alors installons également ces bibliothèques :

pip install pandas pyarrow

Interroger un fichier JSON dans S3

Voyons maintenant comment interroger un fichier JSON stocké dans un bucket S3. Le jeu de données YouTube dislikes contient plus de 4 milliards de lignes correspondant à des réactions « Je n’aime pas » sur des vidéos YouTube jusqu’en 2021. Nous allons travailler avec l’un des fichiers JSON de ce jeu de données.

Importez chdb:

import chdb

Nous pouvons écrire la requête suivante pour décrire la structure de l’un des fichiers 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)"

Nous pouvons également compter le nombre de lignes dans ce fichier :

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

Ce fichier contient un peu plus de 300 000 enregistrements.

chdb ne permet pas encore de passer des paramètres de requête, mais nous pouvons extraire le chemin et le transmettre à l’aide d’une 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')
  """
)

Configurer le format de sortie

Le format de sortie par défaut est CSV, mais il peut être modifié via le paramètre output_format. chDB prend en charge les formats de données de ClickHouse, ainsi que certains formats qui lui sont propres, dont DataFrame, qui renvoie un 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

Ou, si nous voulons récupérer une table 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]]

Créer une table à partir d’un fichier JSON

Voyons maintenant comment créer une table dans chDB. Pour cela, nous devons utiliser une API différente. Commençons donc par l’importer :

from chdb import session as chs

Ensuite, nous allons initialiser une session. Si nous voulons que la session soit enregistrée sur disque, nous devons fournir un nom de répertoire. Si nous le laissons vide, la session est temporaire : chDB conserve ses données dans un répertoire temporaire sur disque et les supprime lorsque la session est fermée ; elles ne sont donc pas conservées.

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

Ensuite, nous allons créer une base de données :

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

Nous pouvons maintenant créer une table dislikes à partir du schéma du fichier JSON, en utilisant la technique CREATE...EMPTY AS. Nous utiliserons le paramètre schema_inference_make_columns_nullable afin que les types de colonnes ne deviennent pas tous 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
  """
)

Nous pouvons ensuite utiliser la commande DESCRIBE pour examiner le schéma :

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"

Ensuite, alimentons cette table :

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

Nous pouvons également effectuer ces deux étapes d’un seul coup, à l’aide de la technique CREATE...AS. Créons une autre table avec cette technique :

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

Interroger une table

Enfin, interrogeons la table :

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

Disons que nous ajoutons ensuite une colonne supplémentaire au DataFrame pour calculer le ratio entre les J’aime et les Je n’aime pas. Nous pourrions écrire le code suivant :

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

Interroger un DataFrame Pandas

Nous pouvons ensuite interroger ce DataFrame à partir de 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

Vous pouvez également en savoir plus sur l’interrogation des DataFrame Pandas dans le guide du développeur sur l’interrogation des DataFrame Pandas.

Étapes suivantes

Nous espérons que ce guide vous a donné un bon aperçu de chDB. Pour en savoir plus sur son utilisation, consultez les guides destinés aux développeurs ci-dessous :

Navigation