Synopsis
Description
Le module chdb_hook s’intègre à la commande PostgreSQL COPY afin d’utiliser chDB pour copier des donnéesTO ou FROM l’un des
formats de données pris en charge par chDB, dans des fichiers locaux, des buckets AWS S3,
Google Cloud Storage, et bien d’autres. Il s’intègre également à CREATE TABLE, si bien qu’une
table peut déduire ses colonnes et charger ses lignes depuis n’importe laquelle de ces mêmes
cibles.
Chargement
Chargez chdb_hook de l’une des façons suivantes en tant que superutilisateur. Utilisez celle qui correspond le mieux à votre cas d’utilisation :-
Explicitement, via la commande LOAD ; valable pour la durée d’une session :
La SQL Console de ClickHouse Cloud ne prend pas encore en charge la commande
LOAD 'chdb_hook', mais celle-ci peut être exécutée via psql ou toute autre connexion à la base de données. Sinon, contactez votre interlocuteur Support pour l’ajouter à la configuration de votre service Postgres ; elle pourra ensuite être utilisée dans la SQL Console. -
Pour toutes les sessions, via le paramètre [session_preload_libraries], dans
postgresql.conf:Ou via ALTER SYSTEM :Ce paramètre peut également être défini base de données par base de données via ALTER DATABASE :Ou pour des utilisateurs et des groupes spécifiques via ALTER ROLE : -
Au démarrage du serveur, via le paramètre [shared_preload_libraries], afin qu’il soit
toujours disponible pour toutes les sessions et toutes les bases de données :
Surcharge de COPY
Lors du chargement, chdb_hook se greffe sur la commande Postgres COPY pour copier des donnéesTO ou FROM l’un quelconque des formats de données pris en
charge par chDB, dans des fichiers locaux, des buckets AWS S3,
Google Cloud Storage, et bien plus encore. Pour charger une table depuis un CSV file
dans S3, par exemple, créez la table puis appelez COPY avec une URL s3:// :
Privilèges
UnCOPY chdb_hook requiert les mêmes privilèges que le COPY qu’il remplace :
SELECT sur la relation ou sur chaque colonne copiée pour COPY TO, et INSERT
pour COPY FROM. Une URL file:// lit ou écrit un fichier sur le serveur, et
requiert donc également l’appartenance à pg_read_server_files ou pg_write_server_files.
COPY FROM requiert une transaction en lecture-écriture.
Schémas d’URL
chdb_hook ne s’exécute que pour les ciblesCOPY de type URL utilisant l’un des
schémas suivants :
Formats d’URL
Le format des URL varie selon le target.File
Doit être un chemin absolu sur le serveur Postgres. Un chemin relatif provoque une erreur. L’utilisateur Postgres doit être membre du rôlepg_read_server_files ou
pg_write_server_files, selon le cas. L’utilisateur système Postgres doit
disposer d’un accès en lecture ou en écriture au fichier, selon le cas. Pour COPY TO, si le
chemin n’existe pas, chdb_hook créera les répertoires parents manquants ; il
doit pour cela disposer des permissions nécessaires sur le système de fichiers. Exemple :
HTTP
Toute URL HTTP ordinaire, y compris dans un stockage cloud public. PourCOPY TO,
chdb_hook tentera d’envoyer les données à l’URL via POST. Exemple :
S3
Les URL S3 peuvent prendre la forme d’un URI S3GCS
Les URL GCS prennent la forme d’une URL publique :Azure Blob Storage
Utilisez une URLblob.windows.net avec un nom de compte comme sous-domaine :
Azure ABFS
Les URL ABFS doivent utiliser ce format :URL HDFS
Les URL HDFS peuvent adopter la forme classique des URL de type HTTP, avec un port optionnel :Caractères génériques dans les chemins
Les chemins d’URL peuvent contenir des globs dans les commandesCOPY FROM. Les fichiers doivent correspondre au
motif de chemin complet, et non seulement au suffixe ou au préfixe. Seule exception : lorsque le
chemin désigne un répertoire existant et n’utilise pas de globs, un * est
implicitement ajouté au chemin afin de sélectionner tous les fichiers du répertoire.
Les caractères génériques pris en charge :
*: correspond à un nombre quelconque de caractères, à l’exception de/, y compris la chaîne vide.?: correspond à un seul caractère quelconque.{groucho,harpo,chico}: substitue l’une des chaînes “groucho”, “harpo” ou “chico”. Ces chaînes peuvent contenir/.{N..M}: correspond à tout nombre>= Net<= M.**: correspond de manière récursive à tous les fichiers d’un répertoire.
- https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/some_prefix/some_file_1.csv
- https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/some_prefix/some_file_2.csv
- https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/some_prefix/some_file_3.csv
- https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/another_prefix/some_file_1.csv
- https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/another_prefix/some_file_2.csv
- https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/another_prefix/some_file_3.csv
{some,another}_prefix pour faire correspondre les deux noms de répertoire et
some_file_{1..3}.csv' pour faire correspondre les fichiers, comme ceci :
Options
La commandeCOPY de chdb_hook prend en charge les options suivantes :
format :
Le format à lire ou à écrire. Doit être l’un des formats proposés par chDB,
parmi lesquels TSV, CSV, Parquet, Iceberg, JSON, et bien d’autres. Omettez-le ou définissez-le sur
auto pour laisser chDB déduire le format à partir de l’extension du nom de fichier figurant à la fin
de l’URL.
structure
La structure de données chDB d’une ligne. Elle se compose d’une liste de noms de colonnes,
de ClickHouse data types et de modificateurs. Si elle est omise, chdb_hook fait correspondre les
types de données Postgres à des types ClickHouse généralement appropriés ; voir Postgres vers
chDB pour plus de détails. Si la valeur est auto, chDB tente d’inférer
les types.
Exemple :
access_key et access_secret
Credentials à long terme de l’utilisateur du compte AWS permettant d’authentifier les requests.
- S3 : un [access key ID et access secret] AWS, souvent définis à l’aide des
environment variables
AWS_ACCESS_KEY_IDetAWS_SECRET_ACCESS_KEY - GCS : un HMAC key and secret GCP
- Azure : un nom de storage account Azure et une access key
session_token
Token de session AWS à utiliser avec access_key et access_secret, souvent
défini par la variable d’environnement AWS_SESSION_TOKEN. Utilisé uniquement pour les
URL S3.
compression
Format de compression du fichier. À utiliser lorsque la compression ne peut pas
être déduite du nom du fichier. Valeurs prises en charge :
auto(par défaut)nonegzipougzbrotlioubrxzouLZMAzstdouzstlz4bz2snappy
timeout
Timeout de requête en millisecondes. S’applique aux URL HTTP, S3, GCS et Azure.
Valeur par défaut : 30000 (30 s).
encoding_check
Définit le traitement des caractères invalides au regard de l’[encodage de la base de données][database encoding] lors de
la conversion des valeurs String et JSON de chDB. Valeurs possibles :
fail(par défaut) : lève une erreurremovesupprime les octets invalidesreplace: avec l’encodage UTF-8, remplace les octets invalides par le caractère de remplacement Unicode (�) ; équivaut àremovepour les autres encodagestruncatetronque le texte au premier octet invalide
Débogage
En cas d’erreur, la commandeCOPY de chdb_hook inclut la requête chDB qu’elle
a tenté d’exécuter dans le contexte de l’erreur :
{name:Type} pour les query parameters afin de se prémunir contre les vulnérabilités d’injection SQL et de limiter le risque de consigner des données sensibles telles que des credentials.
Si vous avez toutefois besoin de consulter le contenu de ces parameters pour déboguer un issue, définissez temporairement le GUC Postgres [log_min_messages] sur DEBUG1 ou une valeur supérieure : chdb_hook enverra alors la query et les parameters dans le log Postgres (jamais au client), où ils apparaîtront ainsi :
Surcharge de CREATE TABLE
chdb_hook s’accroche également à CREATE TABLE, ce qui permet à une table de dériver ses colonnes et de charger ses lignes depuis une URL. Pour créer une table dont la structure est dérivée d’une URL, passez l’URL dans l’optionstructure_from et laissez la liste de colonnes vide (attention : ce fichier de données
public contient 41 millions de lignes) :
copy_from pour charger les lignes ainsi que les colonnes :
copy_from n’infère les colonnes que lorsque le statement n’en nomme aucune
lui-même. Une liste de colonnes, une clause INHERITS, un type OF ou une partition
définissent chacun des colonnes : copy_from ne copie alors que :
copy_from infère les colonnes, il utilise le schéma source renvoyé par DESCRIBE.
Les valeurs Map, Tuple et Nested sont ainsi chargées sous forme de colonnes de tableaux de texte,
qui ne conservent pas leurs types ClickHouse d’origine.
Les deux options prennent en charge les mêmes schémas d’URL et
options que COPY : credentials, format, compression, timeout et
même une structure explicite, tout s’applique. Postgres conserve
les paramètres de stockage restants :
structure_from ni copy_from ne fonctionnent avec IF NOT EXISTS. Utilisez
COPY pour charger une relation existante.
Limitations
En raison de quelques problèmes connus et de différences de comportement des types de données entre Postgres et chDB, chdb_hook présente les limitations suivantes :- Impossible d’effectuer un
COPYsur des relations dont les politiques de row-level security s’appliquent au rôle effectuant la copie. Postgres applique ces politiques en réécrivantCOPY TOsous forme de requête, ce que chdb_hook ne prend pas en charge. - Impossible d’effectuer un
COPY FROMdepuis une URL avec une clauseWHERE. - chDB ne dispose pas de tableau NULL :
COPY TOstocke donc un tableau vide ([]) pour un NULL. - chDB représente les équivalents de
lseg,pathoupolygonsous forme de tableaux ; les valeurs NULL de ces types sont donc elles aussi converties parCOPY TOen tableau vide ([]). - ClickHouse ne dispose pas de tableau NULL :
COPY TOstocke donc un tableau vide ([]) pour unNULL. - ClickHouse représente les équivalents de
lseg,pathoupolygonsous forme de tableaux ; les valeurs NULL de ces types sont donc elles aussi converties parCOPY TOen tableau vide ([]). - Les valeurs NULL produites pour une structure spécifiée qui ne définit pas la colonne comme Nullable seront émises sous forme de valeurs par défaut. Définissez toujours explicitement les colonnes nullables dans la structure pour éviter cette conversion.
- Un
pathouvert dont le dernier point est identique au premier est émis comme un chemin fermé. - Protobuf n’admet pas de valeur null dans un champ répété : il omet donc les valeurs NULL dans les tableaux.
- Le JSON type de chDB ne prend en charge que les objets JSON ; ne remplacez le mappage
Stringpar défaut dejsonetjsonbparJSONque si toutes les valeurs sont des objets JSON. (ClickHouse/ClickHouse#68428) - Le JSON type de chDB ignore les
null; les clés d’objet dont la valeur est NULL seront omises en sortie. Ne remplacez le mappageStringpar défaut dejsonetjsonbparJSONque si les valeurs des objets ne sont pasnullou si leur perte est acceptable. (ClickHouse/ClickHouse#68428) - Les formats JSON, JSONCompact et JSONColumnsWithMetadata valident toujours l’UTF-8 ; ils émettent donc les valeurs bytea avec des caractères de remplacement.
COPY FROMinterprète un champ ProtobufNullablecontenant une chaîne vide ou un zéro commeNULL. (chdb-io/chdb-core#152)COPY TOen Parquet supprime lesNULLdu null map propre à un Tuple Nullable. (ClickHouse/ClickHouse#112427)- Les formats Parquet, Arrow, ArrowStream, ORC, Avro, Protobuf, ProtobufList, MsgPack
et BSONEachRow n’ont aucun type correspondant au type
timede Postgres ouTime64de chDB. Configurez les colonnestimecomme desStringdans une structure explicite pour préserver leurs valeurs. - La sortie Protobuf tronque les valeurs timestamp à la seconde.
- La sortie Protobuf ne prend pas en charge les dates antérieures au 1970-01-01. Configurez les colonnes
timecomme desStringdans une structure explicite pour préserver leurs valeurs. (ClickHouse/ClickHouse#111860)
Types de données
COPY fait correspondre les types Postgres d’une relation aux types chDB, tandis que CREATE TABLE fait correspondre les types chDB d’une URL aux types Postgres.De Postgres vers chDB
En l’absence d’option structure explicite, chdb_hook fait correspondre les types Postgres à des équivalents chDB adaptés. S’ils ne conviennent pas à votre cas d’usage, spécifiez la structure pour remplacer les types générés par ceux dont vous avez besoin.
Les types absents de ce tableau, tels que
name, varchar, char, bit,
timetz, money et les enums, correspondent à String.
Les types tableau correspondent à des Array du type d’élément correspondant. ClickHouse définit
la nullabilité par colonne, tandis que Postgres la définit par tableau ; les éléments sont donc
toujours Nullable.
Aucun type Postgres ne correspond directement à Map, Tuple ou Nested, mais une
structure ou un fichier source peut en spécifier un. Un Tuple peut être lu
dans text[], avec un élément par champ du tuple, ou dans un [type
composite] correspondant afin de conserver les types des champs. Un Map ou un Nested peut être lu dans
text[][], avec un tableau interne par paire clé-valeur ou par tuple imbriqué, ou dans
un tableau d’un type composite correspondant. Consultez Correspondances de types
manuelles pour des exemples.
Conversion des timestamps
Dans les formats texte brut (TSV, CSV, etc.), le hookCOPY émet les valeurs DateTime et
DateTime64 au format ISO-8601, YYYY-MM-DDThh:mm:ssZ, sans tenir compte
du paramètre datestyle courant. Cela garantit que les valeurs timestamptz
restent cohérentes, même si une source qui importe ces valeurs utilise une time zone
différente. L’utilisation d’un type différent dans la sortie structure, tel que Datetime64(3, 'America/Los_Angeles'), n’a aucun effet sur le décalage de la sortie, mais
modifie la precision.
Exemples de timestamp TZ :
Le hook
COPY convertit également les valeurs timestamp de la session time zone vers
UTC, ce qui garantit qu’elles sont émises par rapport à cette time zone. Une fois chargées
dans un nouveau système, celui-ci devrait les convertir vers sa time zone locale. Les
valeurs différeront donc si la time zone diffère, mais resteront identiques
compte tenu de l’écart entre les time zones.
Exemple de l’effet du paramètre timezone sur le timestamp
2026-08-28T12:00:00 :
De chDB vers Postgres
Pour les tables existantes, les valeurs sont converties dans les types de colonne déclarés. Les autres types scalaires utilisent les conversions explicites de PostgreSQL lorsqu’elles existent, et les éléments de tableau sont convertis dans le type d’élément déclaré. Les conversions non prises en charge et les valeurs hors plage déclenchent des erreurs. Associez les types chDBInterval à smallint, integer ou bigint pour lire et
écrire le nombre de leurs unités. Par exemple, une valeur IntervalDay de 3 correspond
à l’entier 3. Associer IntervalNanosecond à bigint conserve les
nanosecondes, tandis que l’associer à interval tronque la valeur à la microseconde.
chdb_hook utilise les types Postgres par défaut ci-dessous lorsqu’il crée des tables à partir des
types ClickHouse renvoyés par DESCRIBE. Les cibles de lecture supplémentaires s’appliquent aux
colonnes déclarées explicitement et incluent des conversions qui vont au-delà des conversions explicites
de PostgreSQL. Lorsque la cellule est vide, ces conversions restent possibles. Ces cibles concernent uniquement les lectures ;
les écritures obéissent à des règles de conversion distinctes.
Les types compatibles en entrée peuvent lire des chaînes de caractères à l’aide de leur fonction d’entrée PostgreSQL.
Les types composites doivent avoir des champs correspondants, dans le même ordre. Pour lire un tuple
sous forme de tableau, chaque champ doit pouvoir être converti vers le type d’élément du tableau, et aucun champ
ne peut lui-même être un tableau.
Lorsqu’ils sont lus sous forme de tableau,
Map utilise une ligne par paire clé-valeur et Nested
une ligne par ligne imbriquée. Pour lire un tuple en tant que box, fournissez deux points ; pour
circle, fournissez un point et un rayon ; pour line, fournissez trois coefficients.
Tout type chDB absent de ce tableau lève une erreur, notamment Variant,
Dynamic et AggregateFunction. Utilisez une structure qui les associe à
String pour les lire sous forme de texte.
Pour certains de ces types, Postgres couvre une plage plus étroite que chDB ; la copie
lève donc une erreur sur un Time ou un Time64 dépassant 24 heures, ainsi que sur un Date32
situé en dehors de la plage de dates de Postgres.
Correspondances de types manuelles
L’inférence des colonnes utilisetext pour les enums et des tableaux de texte pour les valeurs Tuple, Map
et Nested. Pour conserver les types des champs ou restreindre les valeurs d’enum, créez
des types enum et des types composites PostgreSQL, puis déclarez les colonnes avec ces types.
Spécifiez les types chDB avec structure, ou utilisez structure 'auto'
pour les inférer à partir des données sources plutôt qu’à partir de la table Postgres. Par
exemple, utilisez ces types pour charger des statuts d’événements, des coordonnées, des labels et
des éléments imbriqués :
Map, déclarez un champ clé suivi d’un champ valeur. Chaque
Tuple devient une valeur composite ; chaque paire Map ou ligne Nested devient
un élément d’un tableau composite.
Dans une structure explicite, chDB découpe un Nested en une colonne Array par
champ. Utilisez Array(Tuple(...)) pour lire les lignes imbriquées dans une seule colonne
de type tableau composite, comme illustré ci-dessus, ou utilisez structure 'auto' avec un format source
chDB qui inclut des informations de type.
Encodage du texte
chDB litString, FixedString, Enum et JSON sous forme d’octets, sans
aucune garantie quant à l’encodage. La copie d’une telle colonne vers text, ou vers
tout autre type non binaire, vérifie les octets au regard de l’encodage de la base de données et lève une erreur
pour les données qui ne peuvent pas être représentées :
text.
Copiez dans bytea pour conserver les octets tels que chDB les a écrits. Nommez-les ainsi, car
CREATE TABLE dérive text pour ces types :
FixedString(N) complète les valeurs plus courtes avec des octets NUL. La copie vers text supprime
les NUL de fin, tandis que bytea conserve la totalité des N octets.
Paramètres
chdb_hook.max_memory
max_memory_usage. Nécessite les privileges de superuser. Indiquez un integer
correspondant au nombre de mégaoctets, ou une valeur suivie de l’une des unités de mémoire suivantes :
B(octets)kB(kilooctets)MB(mégaoctets)GB(gigaoctets)TB(téraoctets)
0 par défaut, ce qui signifie aucune limite de mémoire.
chdb_hook.max_threads
max_threads. Nécessite le privilège de superuser. La valeur par défaut est 0, ce qui laisse chDB déterminer la valeur.
Nous recommandons vivement de définir chdb_hook.max_threads avant d’exécuter un COPY volumineux, afin d’éviter que chDB ne sature le CPU au détriment de PostgreSQL.
chdb_hook.max_parsing_threads
max_parsing_threads. Nécessite les privilèges de superuser. La valeur par défaut est 0, ce qui laisse chDB déterminer la valeur.
Nous recommandons de définir chdb_hook.max_parsing_threads avant d’effectuer un COPY sur un grand volume de données, afin d’éviter que chDB ne sature l’utilisation du CPU au détriment de PostgreSQL.
Politique de versionnage
chdb_hook respecte le Semantic Versioning pour ses releases publiques.- La major version est incrémentée en cas de changements d’API
- La minor version est incrémentée en cas de changements SQL rétrocompatibles
- La version de patch est incrémentée en cas de changements portant uniquement sur le binary
pg_get_loaded_modules() de Postgres 18.