Skip to main content

Sinopsis

Descripción

El módulo chdb_hook se engancha al comando COPY de PostgreSQL para usar chDB y copiar datos TO o FROM cualquiera de los formatos de datos compatibles que ofrece chDB, ya sea en archivos locales, buckets de AWS S3, Google Cloud Storage y más. También se engancha a CREATE TABLE, de modo que una tabla puede derivar sus columnas y cargar sus filas desde cualquiera de esos mismos destinos.

Carga

Cargue chdb_hook de una de las siguientes maneras como super user. Utilice la que resulte más adecuada para su caso de uso:
  • Explícitamente mediante el comando LOAD; se mantiene durante toda la session:
    La SQL Console de ClickHouse Cloud aún no admite el comando LOAD 'chdb_hook', pero puede ejecutarse mediante psql o cualquier otra conexión a la base de datos. De lo contrario, póngase en contacto con su representante de soporte para añadirlo a la configuración de su service de Postgres, tras lo cual podrá utilizarse en la SQL Console.
  • Para todas las sessions, mediante el setting [session_preload_libraries], en postgresql.conf:
    O mediante ALTER SYSTEM:
    Este setting también puede establecerse por base de datos mediante ALTER DATABASE:
    O para usuarios y grupos específicos mediante ALTER ROLE:
  • Al iniciar el servidor, mediante el setting [shared_preload_libraries], de modo que esté siempre disponible para todas las sessions y bases de datos:
Tenga en cuenta que cargar chdb_hook permite a los usuarios con los roles pg_read_server_files o pg_write_server_files ejecutar COPY para copiar datos desde y hacia archivos del servidor de Postgres, así como en almacenamiento en la nube.

Sobrecarga de COPY

Durante la carga, chdb_hook se engancha al comando COPY de Postgres para copiar datos TO o FROM cualquiera de los formatos de datos compatibles que proporciona chDB en archivos locales, buckets de AWS S3, Google Cloud Storage y más. Por ejemplo, para cargar una tabla desde un archivo CSV en S3, cree la tabla y luego llame a COPY con una URL s3://:

Privilegios

Un COPY de chdb_hook requiere los mismos privilegios que el COPY al que reemplaza: SELECT sobre la relación o sobre cada columna copiada en el caso de COPY TO, e INSERT en el de COPY FROM. Una URL file:// lee o escribe un archivo en el servidor, por lo que también exige pertenecer a pg_read_server_files o pg_write_server_files. COPY FROM requiere una transacción de lectura-escritura.

Esquemas de URL

chdb_hook solo se ejecuta para destinos COPY de tipo URL que utilicen uno de los siguientes esquemas:

Formatos de URL

El formato de las URL varía según el destino.

File

Debe ser una ruta absoluta en el servidor de Postgres. Una ruta relativa provoca un error. El usuario de Postgres debe ser miembro del rol pg_read_server_files o pg_write_server_files, según corresponda. El usuario del sistema de Postgres debe tener acceso de lectura o escritura al archivo, según corresponda. En el caso de COPY TO, si la ruta no existe, chdb_hook creará los directorios padre que falten; para ello debe contar con los permisos necesarios en el sistema de archivos. Ejemplo:

HTTP

Cualquier URL HTTP normal, incluidas las de almacenamiento en la nube público. Para COPY TO, chdb_hook intentará enviar los datos a la URL mediante POST. Ejemplo:

S3

Las URL de S3 pueden tener la forma de un URI de S3
O de una URL de objeto:

GCS

Las URL de GCS tienen el formato de una URL pública:
O un URI de Cloud Storage, que chdb_hook convierte en una URL pública:

Azure Blob Storage

Utilice una URL blob.windows.net con el nombre de la cuenta como subdominio:
O utilice otro nombre del host:

Azure ABFS

Las URL de ABFS deben usar este formato:

URL de HDFS

Las URL de HDFS pueden usar URL con el estilo típico de HTTP y un puerto opcional:

Comodines de ruta

Las rutas URL pueden contener globs en los comandos COPY FROM. Los archivos deben coincidir con el patrón de ruta completo, no solo con el sufijo o el prefijo. La única excepción: cuando la ruta hace referencia a un directorio existente y no usa globs, se añadirá implícitamente un * a la ruta para seleccionar todos los archivos del directorio. Comodines admitidos:
  • *: Coincide con cualquier cantidad de caracteres excepto /, incluida la cadena vacía.
  • ?: Coincide con un único carácter arbitrario.
  • {groucho,harpo,chico}: Sustituye cualquiera de las cadenas “groucho”, “harpo” y “chico”. Las cadenas pueden contener /.
  • {N..M}: Coincide con cualquier número >= N y <= M.
  • **: Coincide recursivamente con todos los archivos de un directorio.
Por ejemplo, para cargar datos de estos archivos con un solo comando: Use {some,another}_prefix para hacer coincidir los dos nombres de directorio y some_file_{1..3}.csv' para los archivos, de este modo:

Opciones

El comando COPY de chdb_hook admite las siguientes opciones:

format:

El formato de lectura o escritura. Debe ser uno de los formats que ofrece chDB, entre los que se incluyen TSV, CSV, Parquet, Iceberg, JSON y otros. Omítalo o establézcalo en auto para que chDB determine el formato a partir de la extensión del nombre del archivo al final de la URL.

structure

La estructura de datos de chDB para una fila. Consta de una lista de nombres de columnas, [tipos de datos de ClickHouse] y modificadores. Si se omite, chdb_hook asigna los tipos de datos de Postgres a tipos de ClickHouse generalmente apropiados; consulte Postgres a chDB para más detalles. Si se establece en auto, chDB intenta inferir los tipos. Ejemplo:

access_key y access_secret

Credenciales de larga duración del usuario de la cuenta de AWS para autenticar las solicitudes.
  • S3: Un [ID de clave de acceso y clave secreta de acceso] de AWS, definidos habitualmente mediante las variables de entorno AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY
  • GCS: Una [clave HMAC y su secreto] de GCP
  • Azure: Un nombre de cuenta de Azure Storage y su [clave de acceso]

session_token

Token de sesión de AWS que se usa junto con access_key y access_secret, definido habitualmente por la variable de entorno AWS_SESSION_TOKEN. Se utiliza únicamente para URL de S3.

compression

Formato de compresión del archivo. Úselo si la compresión no puede inferirse a partir del nombre del archivo. Valores admitidos:
  • auto (predeterminado)
  • none
  • gzip o gz
  • brotli o br
  • xz o LZMA
  • zstd o zst
  • lz4
  • bz2
  • snappy

timeout

Tiempo de espera de la solicitud en milisegundos. Se aplica a las URL de HTTP, S3, GCS y Azure. El valor predeterminado es 30000 (30 s).

encoding_check

Define cómo gestionar los caracteres no válidos según la [codificación de la base de datos] al convertir valores String y JSON de chDB. Valores posibles:
  • fail (predeterminado): genera un error
  • remove elimina los bytes no válidos
  • replace: con la codificación UTF-8, reemplaza los bytes no válidos por el carácter de reemplazo de Unicode (�); en otras codificaciones, equivale a remove
  • truncate trunca el texto en el primer byte no válido

Depuración

Cuando se produce un error, el comando COPY de chdb_hook incluye en el contexto del error la consulta de chDB que intentó ejecutar:
chdb_hook utiliza placeholders con el estilo {name:Type} para los parámetros de consulta con el fin de protegerse frente a vulnerabilidades de injection de SQL y minimizar el riesgo de registrar datos sensibles como credenciales. No obstante, si necesitas ver el contenido de esos parámetros para depurar un issue, configura temporalmente el GUC [log_min_messages] de Postgres con el valor DEBUG1 o superior para que chdb_hook envíe la consulta y los parámetros al log de Postgres (nunca al client), donde aparecerán así:
No mantenga [log_min_messages] en un nivel de depuración más allá de una única sesión de depuración, tanto para evitar registrar información sensible como las credenciales, como porque el propio PostgreSQL también registra información de depuración y puede llenar el log con rapidez.

Sobrecarga de CREATE TABLE

chdb_hook también se engancha a CREATE TABLE, de modo que una tabla puede derivar sus columnas y cargar sus filas desde una URL. Para crear una tabla cuya estructura se derive de una URL, pase la URL en la opción structure_from y deje vacía la lista de columnas (atención: este archivo de datos público contiene 41 millones de filas):
Use copy_from para cargar tanto las filas como las columnas:
copy_from infiere las columnas solo cuando el statement no declara ninguna propia. Una lista de columnas, una cláusula INHERITS, un type OF o una partición definen columnas, por lo que, en ese caso, copy_from solo copia:
Cuando copy_from infiere las columnas, utiliza el esquema de origen que devuelve DESCRIBE. Esto permite que los valores Map, Tuple y Nested se carguen como columnas de array de texto, que no conservan sus tipos originales de ClickHouse. Ambas opciones admiten los mismos esquemas de URL y las mismas opciones que COPY: se aplican las credenciales, el formato, la compresión, el tiempo de espera e incluso una estructura explícita. Postgres conserva los parámetros de almacenamiento restantes:
Ni structure_from ni copy_from funcionan con IF NOT EXISTS. Utilice COPY para cargar una relación existente.

Limitaciones

Debido a algunos problemas conocidos y a las variaciones en el comportamiento de los tipos de datos entre Postgres y chDB, chdb_hook presenta las siguientes limitaciones:
  • No se puede hacer COPY de relaciones con políticas de row-level security que se apliquen al rol que realiza la copia. Postgres aplica dichas políticas reescribiendo COPY TO como una consulta, algo que chdb_hook no admite.
  • No se puede hacer COPY FROM desde una URL con una cláusula WHERE.
  • chDB no tiene un array NULL, por lo que COPY TO almacena un array vacío ([]) en lugar de un NULL.
  • chDB representa los equivalentes de lseg, path o polygon como arrays; por lo tanto, los valores NULL de estos tipos también se escriben con COPY TO como un array vacío ([]).
  • ClickHouse no tiene un array NULL, por lo que COPY TO almacena un array vacío ([]) en lugar de un NULL.
  • ClickHouse representa los equivalentes de lseg, path o polygon como arrays; por lo tanto, los valores NULL de estos tipos también se escriben con COPY TO como un array vacío ([]).
  • Los valores NULL emitidos para una estructura especificada que no defina la columna como Nullable se emitirán como sus valores predeterminados. Defina siempre explícitamente las columnas nullable en la estructura para evitar esta conversión.
  • Un path abierto cuyo último punto coincide con el primero se emite como un path cerrado.
  • Protobuf no admite null en un campo repetido, por lo que omite los valores NULL en los arrays.
  • El JSON type de chDB solo admite objetos JSON; sobrescriba la correspondencia predeterminada String de json y jsonb con JSON únicamente si todos los valores son objetos JSON. (ClickHouse/ClickHouse#68428)
  • El JSON type de chDB ignora los null; las claves de objeto con valores NULL se omitirán en la salida. Sobrescriba la correspondencia predeterminada String de json y jsonb con JSON únicamente si los valores del objeto no son null o si su pérdida resulta aceptable. (ClickHouse/ClickHouse#68428)
  • Los formatos JSON, JSONCompact y JSONColumnsWithMetadata siempre validan UTF-8, por lo que emiten los valores bytea con caracteres de reemplazo.
  • COPY FROM lee como NULL un campo Nullable de Protobuf que contenga una cadena vacía o un cero. (chdb-io/chdb-core#152)
  • COPY TO en Parquet descarta los NULL del propio null map de un Tuple Nullable. (ClickHouse/ClickHouse#112427)
  • Los formatos Parquet, Arrow, ArrowStream, ORC, Avro, Protobuf, ProtobufList, MsgPack y BSONEachRow no tienen un tipo equivalente al time de Postgres ni al Time64 de chDB. Configure las columnas time como String en una estructura explícita para preservar sus valores.
  • La salida de Protobuf trunca los valores de timestamp al segundo.
  • La salida de Protobuf no admite fechas anteriores al 1970-01-01. Configure las columnas time como String en una estructura explícita para preservar sus valores. (ClickHouse/ClickHouse#111860)

Tipos de datos

COPY asigna los tipos de Postgres de una relación a tipos de chDB, mientras que CREATE TABLE asigna los tipos de chDB de una URL a tipos de Postgres.

De Postgres a chDB

Si no se indica explícitamente la opción estructura, chdb_hook asigna los tipos de Postgres a equivalentes razonables de chDB. Si estos no se ajustan a su caso de uso, especifique la opción estructura para sobrescribir los tipos generados con los que necesite. Los tipos que no figuran en esta tabla, como name, varchar, char, bit, timetz, money y los enums, se asignan a String. Los tipos array se asignan a Arrays del tipo de elemento correspondiente. ClickHouse restringe la nulabilidad por columna, mientras que Postgres lo hace por array, por lo que los elementos son siempre Nullable. Ningún tipo de Postgres se asigna directamente a Map, Tuple o Nested, pero una estructura o un archivo de origen pueden especificarlos. Un Tuple puede leerse como text[], con un elemento por cada campo de la tupla, o como un [tipo compuesto] equivalente para conservar los tipos de los campos. Un Map o Nested puede leerse como text[][], con un array interno por cada par clave-valor o tupla anidada, o como un array de un tipo compuesto equivalente. Consulte Correspondencias manuales de tipos para ver ejemplos.

Conversión de timestamp

En formatos de texto plano (TSV, CSV, etc.), el hook COPY emite los valores DateTime y DateTime64 en formato ISO-8601, YYYY-MM-DDThh:mm:ssZ, sin tener en cuenta la configuración actual de datestyle. Esto garantiza que los valores timestamptz se mantengan coherentes, incluso si un origen que importa los valores usa una zona horaria distinta. Usar un tipo diferente en la salida de structure, como Datetime64(3, 'America/Los_Angeles'), no afecta al desplazamiento de la salida, pero sí cambia la precision. Ejemplos de timestamp TZ: El hook COPY también convierte los valores timestamp de la session zona horaria a UTC, con lo que se garantiza que se emitan en relación con esa zona horaria. Al cargarlos en un sistema nuevo, este debería convertirlos a su zona horaria local. Por tanto, los valores diferirán si la zona horaria difiere, pero serán equivalentes respecto a la diferencia de zona horaria. Ejemplo del efecto de la configuración timezone sobre el timestamp 2026-08-28T12:00:00:

De chDB a Postgres

En las tablas existentes, los valores se convierten a los tipos de columna declarados. Los tipos escalares alternativos usan las conversiones explícitas de PostgreSQL cuando están disponibles, y los elementos de array se convierten al tipo de elemento declarado. Las conversiones no compatibles y los valores fuera de rango generan errores. Asigne los tipos Interval de chDB a smallint, integer o bigint para leer y escribir el recuento de sus unidades. Por ejemplo, un valor IntervalDay de 3 se corresponde con el integer 3. Si asigna IntervalNanosecond a bigint, se conservan los nanosegundos, mientras que si lo asigna a interval, se trunca a microsegundos. chdb_hook usa los tipos predeterminados de Postgres que se indican a continuación al crear tablas a partir de los tipos de ClickHouse que devuelve DESCRIBE. Los destinos de lectura adicionales se aplican a las columnas declaradas explícitamente e incluyen conversiones que van más allá de las conversiones explícitas de PostgreSQL. Las celdas vacías siguen admitiendo esas conversiones. Estos destinos se refieren a las lecturas; las escrituras siguen reglas de conversión distintas. Los tipos compatibles con la entrada pueden leer cadenas mediante su función de entrada de PostgreSQL. Los tipos compuestos deben tener campos coincidentes en el mismo orden. Para leer una tupla como array, cada campo debe poder convertirse al tipo de elemento del array, y ningún campo puede ser a su vez un array. Al leerse como array, Map usa una fila por cada par clave-valor y Nested usa una fila por cada fila anidada. Para leer una tupla como box, proporcione dos puntos; para circle, proporcione un punto y un radio; para line, proporcione tres coeficientes. Todo tipo de chDB omitido en esta tabla lanza un error, entre ellos Variant, Dynamic y AggregateFunction. Use una estructura que los asigne a String para leerlos como texto. Postgres admite un rango más estrecho que chDB en algunos de estos tipos; por ello, la copia lanza un error con un Time o Time64 que supere las 24 horas, y con un Date32 fuera del rango de fechas de Postgres.

Correspondencias manuales de tipos

La inferencia de columnas usa text para los enums y arrays de texto para los valores Tuple, Map y Nested. Para conservar los tipos de los campos o restringir los valores de los enums, cree tipos enum y tipos compuestos en PostgreSQL y, a continuación, declare las columnas con esos tipos. Especifique los tipos de chDB con estructura, o use structure 'auto' para inferirlos a partir de los datos de origen en lugar de a partir de la tabla de Postgres. Por ejemplo, use estos tipos para cargar estados de eventos, coordenadas, etiquetas y elementos anidados:
Declare los campos compuestos en el mismo orden de campos que en chDB, usando tipos de PostgreSQL compatibles. Para los valores Map, declare un campo de clave seguido de un campo de valor. Cada Tuple se convierte en un valor compuesto; cada par de Map o fila de Nested se convierte en un elemento de un array compuesto. Cuando se usa una structure explícita, chDB divide Nested en una columna Array por cada campo. Use Array(Tuple(...)) para leer las filas anidadas en una única columna de array compuesto, como se muestra arriba, o use structure 'auto' con un formato de fuente de chDB que incluya información de tipos.

Codificación de texto

chDB lee String, FixedString, Enum y JSON como bytes, sin ninguna garantía de codificación. Al copiar una columna de ese tipo a text, o a cualquier otro tipo no binario, se verifican los bytes según la codificación de la base de datos y se lanza un error para los datos que no se pueden representar:
Todas las codificaciones rechazan los NUL, que Postgres no puede almacenar en text. Copia en bytea para conservar los bytes tal como los escribió chDB. Nombra así estos casos, ya que CREATE TABLE deriva text para estos tipos:
FixedString(N) rellena con bytes NUL los valores más cortos. Al copiarlos a text se descartan los NUL finales, mientras que bytea conserva los N bytes.

Configuración

chdb_hook.max_memory

Define la cantidad máxima de memoria para una consulta de chDB y se utiliza para establecer el ajuste max_memory_usage de chDB. Requiere privilegios de superuser. Utilice un número entero para indicar la cantidad de megabytes o una de las siguientes unidades de memoria:
  • B (bytes)
  • kB (kilobytes)
  • MB (megabytes)
  • GB (gigabytes)
  • TB (terabytes)
El valor predeterminado es 0, que no impone ningún límite de memoria.

chdb_hook.max_threads

El número máximo de subprocesos de procesamiento de consultas para una consulta de chDB, que se usa para establecer el ajuste max_threads de chDB. Requiere privilegios de superusuario. Su valor predeterminado es 0, lo que permite que chDB determine el valor. Recomendamos encarecidamente configurar chdb_hook.max_threads antes de ejecutar un COPY de gran tamaño, para evitar que chDB agote el uso de CPU en detrimento de PostgreSQL.

chdb_hook.max_parsing_threads

El número máximo de subprocesos que chDB puede usar para parsear datos en formatos de entrada que admiten parsing en paralelo; se utiliza para definir el ajuste max_parsing_threads de chDB. Requiere privilegios de superusuario. Su valor predeterminado es 0, lo que permite que chDB determine el valor. Recomendamos definir chdb_hook.max_parsing_threads antes de ejecutar un COPY con grandes volúmenes de datos, para evitar que chDB acapare el uso de CPU en detrimento de PostgreSQL.

Política de control de versiones

chdb_hook sigue el control de versiones semántico en sus releases públicas.
  • La versión mayor se incrementa ante cambios en la API
  • La versión menor se incrementa ante cambios de SQL retrocompatibles
  • La versión de patch se incrementa ante cambios que solo afectan al binary
Una vez instalado, PostgreSQL la versión mediante la función pg_get_loaded_modules() de Postgres 18.

Autores

Copyright (c) 2026, ClickHouse