clickhouse-local ou dans des buckets S3, et/ou de créer automatiquement des schémas avant de charger les données dans ClickHouse.
Quand utiliser l’inférence de type
- Structure cohérente - Les données à partir desquelles les types seront inférés contiennent toutes les clés qui vous intéressent. L’inférence de type repose sur l’échantillonnage des données jusqu’à un nombre maximal de lignes ou d’octets. Les données situées après l’échantillon, avec des colonnes supplémentaires, seront ignorées et ne pourront pas être interrogées.
- Types cohérents - Les types de données associés à certaines clés doivent être compatibles, c’est-à-dire qu’il doit être possible de convertir automatiquement un type en un autre.
Détection des types
NDJSON. Dans cette section, nous examinons un jeu de données plus complexe avec des structures imbriquées : le jeu de données arXiv, qui contient 2,5 millions d’articles scientifiques. Chaque ligne de ce jeu de données, fourni au format NDJSON, représente un article scientifique publié. Un exemple de ligne est présenté ci-dessous :
Tuple et Array.
Ce jeu de données est stocké dans un bucket S3 public à l’emplacement s3://datasets-documentation/arxiv/arxiv.json.gz.
Vous pouvez constater que le jeu de données ci-dessus contient des objets JSON imbriqués. Même si vous devez rédiger et versionner vos schémas, l’inférence permet de déduire les types à partir des données. Cela permet de générer automatiquement le DDL du schéma, ce qui évite d’avoir à le construire manuellement et accélère le processus de développement.
Détection automatique du formatEn plus de détecter le schéma, l’inférence de schéma JSON détermine automatiquement le format des données à partir de l’extension du fichier et de son contenu. Le fichier ci-dessus est ainsi automatiquement identifié comme étant au format NDJSON.
DESCRIBE affiche les types qui seront déduits.
Évitez les valeurs NULLVous pouvez constater que de nombreuses colonnes sont détectées comme Nullable. Nous déconseillons d’utiliser le type Nullable sauf en cas de nécessité absolue. Vous pouvez utiliser schema_inference_make_columns_nullable pour contrôler les cas où Nullable est appliqué.
String, et que la colonne update_date a bien été détectée comme Date. La colonne versions a été créée comme Array(Tuple(created String, version String)) pour stocker une liste d’objets, tandis que authors_parsed est défini comme Array(Array(String)) pour les tableaux imbriqués.
Contrôle de la détection des typesLa détection automatique des dates et des valeurs DateTime peut être contrôlée respectivement à l’aide des paramètres
input_format_try_infer_dates et input_format_try_infer_datetimes (tous deux activés par défaut). L’inférence d’objets sous forme de tuples est contrôlée par le paramètre input_format_json_try_infer_named_tuples_from_objects. D’autres paramètres qui contrôlent l’inférence de schéma pour le JSON, comme la détection automatique des nombres, sont disponibles ici.Interroger des données JSON
Création de tables
CREATE AS EMPTY suivante permet d’inférer le DDL de la table et de créer celle-ci. Cela ne charge aucune donnée :
SHOW CREATE TABLE :
input_format_max_rows_to_read_for_schema_inference (25000 par défaut) et input_format_max_bytes_to_read_for_schema_inference (32MB par défaut). Si la détection est incorrecte, vous pouvez fournir des indications comme décrit ici.
Création de tables à partir d’extraits
Chargement de données JSON
INSERT INTO SELECT suivante :
PrettyJSONEachRow pour afficher les lignes dans leur structure d’origine :
Gestion des erreurs
input_format_allow_errors_num et input_format_allow_errors_ratio pour autoriser l’ignorance d’un certain nombre de lignes si les données provoquent des erreurs d’insertion. De plus, des indications peuvent être fournies pour faciliter l’inférence.
Travailler avec des données semi-structurées et dynamiques
JSON dédié.
Si vous savez que votre JSON est très dynamique, avec un grand nombre de clés uniques et plusieurs types possibles pour une même clé, nous vous recommandons de ne pas utiliser l’inférence de schéma avec JSONEachRow pour essayer d’inférer une colonne pour chaque clé, même si les données sont au format JSON délimité par des retours à la ligne.
Prenons l’exemple suivant, issu d’une version enrichie du jeu de données Python PyPI dataset présenté plus haut. Nous y avons ajouté une colonne tags arbitraire contenant des paires clé-valeur aléatoires.
JSONEachRow est utilisé pour l’inférence. Il tente d’inférer un type de colonne pour chaque clé du JSON — autrement dit, d’appliquer un schéma statique aux données sans utiliser le type JSON.
Avec des milliers de colonnes uniques, cette approche de l’inférence est lente. À la place, vous pouvez utiliser le format JSONAsObject.
JSONAsObject traite l’entrée entière comme un seul objet JSON et la stocke dans une seule colonne de type JSON, ce qui le rend plus adapté aux payloads JSON très dynamiques ou imbriqués.
sample.json contenant le JSON délimité par des retours à la ligne suivant :
a comme un Nullable(String).
Conversion de typeCette conversion de type peut être contrôlée à l’aide d’un certain nombre de paramètres. L’exemple ci-dessus dépend du paramètre
input_format_json_read_numbers_as_strings.DESCRIBE échoue donc :
JSONAsObject considère chaque ligne comme une unique valeur de type JSON (ce qui permet à une même colonne d’avoir plusieurs types). C’est essentiel :