Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Interfaz HTTP

Requisitos previos

Para los ejemplos de este artículo, necesitará:

  • tener una instancia de ClickHouse server en funcionamiento
  • tener curl instalado. En Ubuntu o Debian, ejecute sudo apt install curl o consulte esta documentación para ver las instrucciones de instalación.

Descripción general

La interfaz HTTP le permite usar ClickHouse en cualquier plataforma y desde cualquier lenguaje de programación mediante una API REST. La interfaz HTTP es más limitada que la interfaz nativa, pero ofrece mejor compatibilidad con distintos lenguajes.

De forma predeterminada, clickhouse-server escucha en los siguientes puertos:

  • puerto 8123 para HTTP
  • se puede habilitar el puerto 8443 para HTTPS

Si realiza una solicitud GET / sin ningún parámetro, se devuelve un código de respuesta 200 junto con la cadena "Ok.":

$ curl 'http://localhost:8123/'
Ok.

"Ok." es el valor predeterminado definido en http_server_default_response y puede modificarse si se desea.

Véase también: Consideraciones sobre los códigos de respuesta HTTP.

Interfaz de usuario web

ClickHouse incluye una interfaz de usuario web a la que se puede acceder desde la siguiente dirección:

http://localhost:8123/play

La interfaz web admite la visualización del progreso durante la ejecución de la consulta, la cancelación de consultas y el streaming de resultados. Tiene una función oculta para mostrar gráficas y diagramas de los pipelines de consultas.

Después de ejecutar correctamente una consulta, aparece un botón de descarga que le permite descargar los resultados de la consulta en varios formatos, incluidos CSV, TSV, JSON, JSONLines, Parquet, Markdown o cualquier formato personalizado compatible con ClickHouse. La función de descarga utiliza la caché de consultas para recuperar los resultados de forma eficiente sin volver a ejecutar la consulta. Descargará el conjunto completo de resultados aunque la UI solo haya mostrado una página de muchas.

La interfaz web está diseñada para profesionales como usted.

Captura de pantalla de la interfaz web de ClickHouse

En los scripts de comprobación de estado, use la solicitud GET /ping. Este controlador siempre devuelve "Ok." (con un salto de línea al final). Disponible a partir de la versión 18.12.13. Véase también /replicas_status para comprobar el retraso de la réplica.

$ curl 'http://localhost:8123/ping'
Ok.
$ curl 'http://localhost:8123/replicas_status'
Ok.

Consultas mediante HTTP/HTTPS

Para realizar consultas mediante HTTP/HTTPS hay tres opciones:

  • enviar la solicitud como parámetro URL 'query'
  • usar el método POST.
  • enviar el comienzo de la consulta en el parámetro 'query' y el resto mediante POST

Si la operación se realiza correctamente, recibirá el código de respuesta 200 y el resultado en el cuerpo de la respuesta. Si se produce un error, recibirá el código de respuesta 500 y una descripción del error en el cuerpo de la respuesta.

Las solicitudes que usan GET son 'readonly'. Esto significa que, para las consultas que modifican datos, solo puede usar el método POST. Puede enviar la consulta en el cuerpo del POST o en el parámetro URL. Veamos algunos ejemplos.

En el ejemplo siguiente, se usa curl para enviar la consulta SELECT 1. Tenga en cuenta el uso de la codificación URL para el espacio: %20.

commandbash
curl 'http://localhost:8123/?query=SELECT%201'
Responseresponse
1

En este ejemplo, se usa wget con los parámetros -nv (sin salida detallada) y -O- para mostrar el resultado en la terminal. En este caso, no es necesario usar la codificación de URL para el espacio:

commandbash
wget -nv -O- 'http://localhost:8123/?query=SELECT 1'
1

En este ejemplo, enviamos una solicitud HTTP sin procesar a netcat:

commandbash
echo -ne 'GET /?query=SELECT%201 HTTP/1.0\r\n\r\n' | nc localhost 8123
responseresponse
HTTP/1.0 200 OK
X-ClickHouse-Summary: {"read_rows":"1","read_bytes":"1","written_rows":"0","written_bytes":"0","total_rows_to_read":"1","result_rows":"0","result_bytes":"0","elapsed_ns":"4505959","memory_usage":"1111711"}
Date: Tue, 11 Nov 2025 18:16:01 GMT
Connection: Close
Content-Type: text/tab-separated-values; charset=UTF-8
Access-Control-Expose-Headers: X-ClickHouse-Query-Id,X-ClickHouse-Summary,X-ClickHouse-Server-Display-Name,X-ClickHouse-Format,X-ClickHouse-Timezone,X-ClickHouse-Exception-Code,X-ClickHouse-Exception-Tag
X-ClickHouse-Server-Display-Name: MacBook-Pro.local
X-ClickHouse-Query-Id: ec0d8ec6-efc4-4e1d-a14f-b748e01f5294
X-ClickHouse-Format: TabSeparated
X-ClickHouse-Timezone: Europe/London
X-ClickHouse-Exception-Tag: dngjzjnxkvlwkeua

1

Como puede ver, el comando curl es algo incómodo, ya que los espacios deben codificarse en la URL. Aunque wget codifica todo automáticamente, no recomendamos usarlo porque no funciona bien con HTTP 1.1 cuando se usan keep-alive y Transfer-Encoding: chunked.

$ echo 'SELECT 1' | curl 'http://localhost:8123/' --data-binary @-
1

$ echo 'SELECT 1' | curl 'http://localhost:8123/?query=' --data-binary @-
1

$ echo '1' | curl 'http://localhost:8123/?query=SELECT' --data-binary @-
1

Si una parte de la consulta se envía en el parámetro y otra en el POST, se inserta un salto de línea entre estos dos fragmentos de datos. Por ejemplo, esto no funcionará:

$ echo 'ECT 1' | curl 'http://localhost:8123/?query=SEL' --data-binary @-
Code: 59, e.displayText() = DB::Exception: Syntax error: failed at position 0: SEL
ECT 1
, expected One of: SHOW TABLES, SHOW DATABASES, SELECT, INSERT, CREATE, ATTACH, RENAME, DROP, DETACH, USE, SET, OPTIMIZE., e.what() = DB::Exception

Por defecto, los datos se devuelven en el formato TabSeparated.

La cláusula FORMAT se usa en la consulta para solicitar cualquier otro formato. Por ejemplo:

commandbash
wget -nv -O- 'http://localhost:8123/?query=SELECT 1, 2, 3 FORMAT JSON'
Responseresponse
{
    "meta":
    [
        {
            "name": "1",
            "type": "UInt8"
        },
        {
            "name": "2",
            "type": "UInt8"
        },
        {
            "name": "3",
            "type": "UInt8"
        }
    ],

    "data":
    [
        {
            "1": 1,
            "2": 2,
            "3": 3
        }
    ],

    "rows": 1,

    "statistics":
    {
        "elapsed": 0.000515,
        "rows_read": 1,
        "bytes_read": 1
    }
}

Puede usar el parámetro de URL default_format para especificar un formato predeterminado distinto de TabSeparated. La cabecera X-ClickHouse-Format selecciona explícitamente el formato de la respuesta: es un alias de la configuración output_format, por lo que también sobrescribe una cláusula FORMAT en la consulta. Nunca cambia cómo se analiza el cuerpo de la solicitud de un INSERT; use input_format o format para ello.

$ echo 'SELECT 1 FORMAT Pretty' | curl 'http://localhost:8123/?' --data-binary @-
┏━━━┓
 1
┡━━━┩
 1
└───┘

Puede usar el método POST con consultas parametrizadas. Los parámetros se especifican entre llaves, con el nombre del parámetro y el tipo, como {name:Type}. Los valores de los parámetros se envían mediante param_name:

$ curl -X POST -F 'query=select {p1:UInt8} + {p2:UInt8}' -F "param_p1=3" -F "param_p2=4" 'http://localhost:8123/'

7

Acceda a las tablas mediante rutas URL y construya consultas

Disponible en ClickHouse 26.8 y versiones posteriores.

La interfaz HTTP puede interpretar una ruta URL como una base de datos, una tabla, un formato de salida y un método de compresión. Los parámetros de URL pueden determinar el resultado, por lo que las solicitudes de lectura sencillas no requieren SQL. Estas funciones están deshabilitadas de forma predeterminada y deben habilitarse explícitamente.

Habilite el enrutamiento por rutas

La interpretación de rutas se habilita en dos niveles:

  1. Habilite el ajuste de configuración http_allow_path_requests a nivel de servidor, que permite a la interfaz HTTP enrutar solicitudes basadas en rutas al controlador de consultas:
<clickhouse>
    <http_allow_path_requests>1</http_allow_path_requests>
</clickhouse>
  1. Habilite los ajustes por usuario necesarios:
Configuración Efecto
http_allow_table_as_file Interpreta el último componente de la ruta como table, table.format o table.format.compression.
http_allow_database_as_path Interpreta un componente inicial de la ruta /database/ como la base de datos actual.
http_allow_filters_as_path Interpreta componentes de ruta /name=value/ de estilo Hive como filtros WHERE.
http_allow_filters_as_unrecognized_url_parameters Interpreta parámetros URL no reconocidos como filtros WHERE.

Acceder a tablas como archivos

Con http_allow_table_as_file habilitado, una solicitud a /table.format.compression se procesa como SELECT * FROM table. Habilite http_allow_database_as_path para usar /database/table.format.compression.

# SELECT * FROM my_db.hits, formatted as CSV
curl 'http://localhost:8123/my_db/hits.csv'

# The same result, compressed with gzip
curl 'http://localhost:8123/my_db/hits.csv.gz' | gzip -d

Las extensiones de formato y compresión se reconocen sin distinguir mayúsculas de minúsculas, por lo que hits.csv y hits.CSV son equivalentes.

Un parámetro URL explícito format u output_format sobrescribe el formato de la ruta. default_format no lo hace: solo proporciona el formato que se debe usar cuando ningún otro lo selecciona, y la extensión de la ruta es más específica. Un parámetro compression explícito debe coincidir con la compresión de la ruta; los valores en conflicto generan una excepción.

Construir una consulta

Los siguientes ajustes encapsulan la consulta base en una tabla derivada. Se pueden combinar entre sí y con una consulta existente. Puede proporcionarlos como parámetros de URL HTTP, en una cláusula SETTINGS de la consulta o mediante un perfil de usuario.

Ajuste Efecto
select SELECT <expression_list> FROM (…)
filter Añade WHERE <expression>. Varios parámetros de URL filter se combinan con AND.
order Añade ORDER BY <expression_list>.
sort Añade ORDER BY a partir de una lista de identificadores o posiciones de columna separada por comas, cada uno con un prefijo opcional + (ascendente) o - (descendente), como sort=a,-b. No se puede combinar con order.
limit y offset Añaden LIMIT <n> OFFSET <m>. Ambos aceptan valores negativos para seleccionar desde el final y valores fraccionarios que representan una proporción de las filas.
page Establece offset = limit * (page - 1). Requiere limit y no se puede combinar con offset.
# Filter my_db.hits, sort by a descending, and return the first 10 rows
curl 'http://localhost:8123/my_db/hits?filter=a%3E0&sort=-a&limit=10'

# Return the second page of 100 rows
curl 'http://localhost:8123/my_db/hits?limit=100&page=2'

Modificar una consulta existente

La configuración de construcción no se limita a las solicitudes de rutas; también da forma a las consultas que escriba. La consulta se convierte en la tabla derivada, por lo que la configuración se aplica a su resultado en lugar de combinarse con ella. Por ejemplo, ?query=SELECT a, b FROM hits&filter=a > 0&sort=-b&limit=10 se ejecuta como:

SELECT * FROM (SELECT a, b FROM hits) WHERE a > 0 ORDER BY b DESC LIMIT 10

Esto resulta útil para paginar, ordenar o restringir el resultado de una consulta definida en otro lugar, ya sea en una consulta guardada en un dashboard, un predefined_query_handler o un cliente que solo permite añadir parámetros de URL:

# Page through the result of an arbitrary query without editing the query text
curl 'http://localhost:8123/?query=SELECT+a,+b+FROM+hits+GROUP+BY+a,+b&limit=100&page=3'

# Keep only some of the resulting columns and rows
curl -G 'http://localhost:8123/' --data-urlencode 'query=SELECT * FROM hits' --data-urlencode 'select=a, b' --data-urlencode 'filter=b != 0'

# The last 5 rows of an aggregate (a negative `limit` selects from the tail)
curl 'http://localhost:8123/?query=SELECT+a,+count()+FROM+hits+GROUP+BY+a+ORDER+BY+a&limit=-5'

Como las configuraciones envuelven la consulta en lugar de reescribirla, son compatibles con una cláusula FORMAT y con un ORDER BY dentro de la consulta, y nunca cambian qué filas inserta un INSERT: una configuración de construcción incluida en una sentencia INSERT ... SELECT da forma al resultado propio (vacío) de la sentencia, no a su SELECT de origen. Para dar forma al origen, incluya la configuración en la cláusula SETTINGS del propio SELECT:

-- Inserts all 10 rows: `limit` applies to the INSERT statement, not to its SELECT
INSERT INTO t SETTINGS limit = 2 SELECT number FROM numbers(10);

-- Inserts 2 rows: `limit` applies to the SELECT itself
INSERT INTO t SELECT number FROM numbers(10) SETTINGS limit = 2;

Sobrescrituras de formatos y compresión

Configuración Efecto
output_format Sobrescribe el formato de salida. Tiene prioridad sobre la cláusula FORMAT de la consulta, la extensión de la ruta, format y default_format. También puede establecerse mediante la cabecera X-ClickHouse-Format.
input_format Sobrescribe el formato de entrada para INSERT. Tiene prioridad sobre la cláusula FORMAT de la consulta y format.
format Sobrescribe el formato en ambas direcciones, salvo que se proporcione una configuración específica para una dirección.
default_format Establece el formato de salida cuando la consulta no tiene cláusula FORMAT, extensión de ruta ni ninguna otra sobrescritura de formato.
compression Comprime el cuerpo de la respuesta, por ejemplo, con compression=gz. Es independiente de HTTP Content-Encoding y del parámetro nativo compress de ClickHouse.

Las configuraciones de formato también funcionan con otros protocolos, incluido el client nativo y clickhouse-local. input_format y output_format corresponden a las opciones --input-format y --output-format. La opción --format se asigna a la configuración bidireccional format en clickhouse-local, mientras que en clickhouse-client conserva su significado histórico de solo salida y se asigna a output_format.

compression es específico de la configuración de respuestas HTTP y se procesa antes de la ejecución de la consulta. Proporciónelo mediante un parámetro de URL HTTP, una extensión de ruta o un perfil de usuario. Se rechaza en una cláusula SETTINGS de la consulta.

Las respuestas HTTP binarias y comprimidas incluyen un encabezado Content-Disposition: attachment; filename=…. El nombre de archivo se deriva de la ruta de la URL o se usa result.<format>.<compression> cuando la ruta no proporciona uno.

Usar una tabla identificada por la ruta con una consulta

Cuando la ruta identifica una tabla y también se proporciona un parámetro query, la tabla identificada por la ruta se expone mediante implicit_table_at_top_level. Un SELECT sin una cláusula FROM lee de la tabla identificada por la ruta:

# Read columns a and b from my_db.hits without a FROM clause
curl 'http://localhost:8123/my_db/hits.CSV?query=SELECT+a,+b'

Si la consulta ya contiene una cláusula FROM, el componente de ruta solo especifica el nombre del archivo descargado.

Consultas INSERT a través de HTTP/HTTPS

El método POST para transmitir datos es necesario para las consultas INSERT. En este caso, puede escribir el comienzo de la consulta en el parámetro de la URL y usar POST para enviar los datos que se van a insertar. Los datos que se van a insertar podrían ser, por ejemplo, un dump de MySQL separado por tabulaciones. De esta manera, la consulta INSERT sustituye a LOAD DATA LOCAL INFILE de MySQL.

Ejemplos

Para crear una tabla:

$ echo 'CREATE TABLE t (a UInt8) ENGINE = Memory' | curl 'http://localhost:8123/' --data-binary @-

Para usar la consulta INSERT habitual para insertar datos:

$ echo 'INSERT INTO t VALUES (1),(2),(3)' | curl 'http://localhost:8123/' --data-binary @-

Para enviar los datos por separado de la consulta:

$ echo '(4),(5),(6)' | curl 'http://localhost:8123/?query=INSERT%20INTO%20t%20VALUES' --data-binary @-

Se puede especificar cualquier formato de datos. Por ejemplo, puede especificarse el formato 'Values', el mismo formato que se usa al escribir INSERT INTO t VALUES:

$ echo '(7),(8),(9)' | curl 'http://localhost:8123/?query=INSERT%20INTO%20t%20FORMAT%20Values' --data-binary @-

Para insertar datos desde un volcado con valores separados por tabulaciones, especifique el formato correspondiente:

$ echo -ne '10\n11\n12\n' | curl 'http://localhost:8123/?query=INSERT%20INTO%20t%20FORMAT%20TabSeparated' --data-binary @-

Para leer el contenido de la tabla:

$ curl 'http://localhost:8123/?query=SELECT%20a%20FROM%20t'
7
8
9
10
11
12
1
2
3
4
5
6

Para eliminar la tabla:

$ echo 'DROP TABLE t' | curl 'http://localhost:8123/' --data-binary @-

En las solicitudes correctas que no devuelven una tabla de datos, se devuelve un cuerpo de respuesta vacío.

Compresión

La compresión puede usarse para reducir el tráfico de red al transmitir una gran cantidad de datos, o para crear volcados que se comprimen de inmediato.

Puede usar el formato de compresión nativo de ClickHouse al transmitir datos. Los datos comprimidos tienen un formato no estándar, y necesita el programa clickhouse-compressor para trabajar con ellos. Se instala de forma predeterminada con el paquete clickhouse-client.

Para aumentar la eficiencia de la inserción de datos, desactive la verificación de checksum del lado del servidor mediante la opción http_native_compression_disable_checksumming_on_decompress.

Si especifica compress=1 en la URL, el servidor comprimirá los datos que le envía. Si especifica decompress=1 en la URL, el servidor descomprimirá los datos que envíe con el método POST.

También puede optar por usar compresión HTTP. ClickHouse admite los siguientes métodos de compresión:

  • gzip
  • br
  • deflate
  • xz
  • zstd
  • lz4
  • bz2
  • snappy

Para enviar una solicitud POST comprimida, agregue la cabecera de solicitud Content-Encoding: compression_method.

Para que ClickHouse comprima la respuesta, agregue la cabecera Accept-Encoding: compression_method a la solicitud.

Puede configurar el nivel de compresión de los datos mediante la opción http_zlib_compression_level para todos los métodos de compresión.

Ejemplos

Para enviar datos comprimidos al servidor:

echo "SELECT 1" | gzip -c | \
curl -sS --data-binary @- -H 'Content-Encoding: gzip' 'http://localhost:8123/'

Para recibir el archivo comprimido de datos del servidor:

curl -vsS "http://localhost:8123/?enable_http_compression=1" \
-H 'Accept-Encoding: gzip' --output result.gz -d 'SELECT number FROM system.numbers LIMIT 3'

zcat result.gz
0
1
2

Para recibir datos comprimidos del servidor, use gunzip para obtener los datos descomprimidos:

curl -sS "http://localhost:8123/?enable_http_compression=1" \
-H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 3' | gunzip -
0
1
2

Base de datos predeterminada

Puede usar el parámetro database de la URL o la cabecera X-ClickHouse-Database para especificar la base de datos predeterminada.

echo 'SELECT number FROM numbers LIMIT 10' | curl 'http://localhost:8123/?database=system' --data-binary @-
0
1
2
3
4
5
6
7
8
9

De forma predeterminada, se usa como base de datos predeterminada la base de datos registrada en la configuración del servidor. De entrada, esta es la base de datos llamada default. Como alternativa, siempre puede especificar la base de datos usando un punto antes del nombre de la tabla.

Autenticación

El nombre de usuario y la contraseña se pueden indicar de una de estas tres formas:

  1. Mediante autenticación básica HTTP.

Por ejemplo:

echo 'SELECT 1' | curl 'http://user:password@localhost:8123/' -d @-
  1. En los parámetros de URL user y password

Por ejemplo:

echo 'SELECT 1' | curl 'http://localhost:8123/?user=user&password=password' -d @-
  1. Uso de las cabeceras 'X-ClickHouse-User' y 'X-ClickHouse-Key'

Por ejemplo:

echo 'SELECT 1' | curl -H 'X-ClickHouse-User: user' -H 'X-ClickHouse-Key: password' 'http://localhost:8123/' -d @-

Si no se especifica el nombre de usuario, se usa el nombre default. Si no se especifica la contraseña, se usa una contraseña vacía. También puede usar los parámetros de URL para especificar cualquier configuración para procesar una sola consulta o perfiles completos de configuración.

Por ejemplo:

http://localhost:8123/?profile=web&max_rows_to_read=1000000000&query=SELECT+1
$ echo 'SELECT number FROM system.numbers LIMIT 10' | curl 'http://localhost:8123/?' --data-binary @-
0
1
2
3
4
5
6
7
8
9

Para más información, consulte:

Uso de sesiones de ClickHouse en el protocolo HTTP

También puede usar sesiones de ClickHouse en el protocolo HTTP. Para ello, debe añadir el parámetro GET session_id a la petición. Puede usar cualquier cadena como ID de sesión.

De forma predeterminada, la sesión finaliza tras 60 segundos de inactividad. Para cambiar este timeout (en segundos), modifique la opción default_session_timeout en la configuración del servidor o añada el parámetro GET session_timeout a la petición.

Para comprobar el estado de la sesión, use el parámetro session_check=1. Solo se puede ejecutar una consulta a la vez dentro de una misma sesión.

Puede recibir información sobre el progreso de una consulta en las cabeceras de respuesta X-ClickHouse-Progress. Para ello, habilite send_progress_in_http_headers.

A continuación se muestra un ejemplo de la secuencia de cabeceras:

X-ClickHouse-Progress: {"read_rows":"261636","read_bytes":"2093088","total_rows_to_read":"1000000","elapsed_ns":"14050417","memory_usage":"22205975"}
X-ClickHouse-Progress: {"read_rows":"654090","read_bytes":"5232720","total_rows_to_read":"1000000","elapsed_ns":"27948667","memory_usage":"83400279"}
X-ClickHouse-Progress: {"read_rows":"1000000","read_bytes":"8000000","total_rows_to_read":"1000000","elapsed_ns":"38002417","memory_usage":"80715679"}

Los posibles campos de cabecera son:

Campo de cabecera Descripción
read_rows Número de filas leídas.
read_bytes Volumen de datos leídos en bytes.
total_rows_to_read Número total de filas que se van a leer.
written_rows Número de filas escritas.
written_bytes Volumen de datos escritos en bytes.
elapsed_ns Tiempo de ejecución de la consulta en nanosegundos.
memory_usage Memoria en bytes utilizada por la consulta. (Disponible a partir de la v25.11)

Las solicitudes en ejecución no se detienen automáticamente si se pierde la conexión HTTP. El análisis sintáctico y el formateo de datos se realizan en el lado del servidor, por lo que usar la red puede resultar ineficiente.

Existen los siguientes parámetros opcionales:

Parámetros Descripción
query_id (optional) Puede pasarse como ID de la consulta (cualquier cadena). replace_running_query
quota_key (optional) Puede pasarse como clave de cuota (cualquier cadena). "Cuotas"

La interfaz HTTP permite pasar datos externos (tablas temporales externas) para realizar consultas. Para obtener más información, consulta "Datos externos para el procesamiento de consultas".

Búfer de respuesta

El búfer de respuesta puede habilitarse en el servidor. Para ello, se proporcionan los siguientes parámetros de URL:

  • buffer_size
  • wait_end_of_query

Se pueden usar los siguientes ajustes:

buffer_size determina cuántos bytes del resultado se almacenarán en el búfer de la memoria del servidor. Si el cuerpo del resultado supera este umbral, el búfer se escribe en el canal HTTP y los datos restantes se envían directamente al canal HTTP.

Para asegurarse de que toda la respuesta quede almacenada en el búfer, establezca wait_end_of_query=1. En este caso, los datos que no se almacenen en memoria se guardarán en un archivo temporal del servidor.

Por ejemplo:

curl -sS 'http://localhost:8123/?max_result_bytes=4000000&buffer_size=3000000&wait_end_of_query=1' -d 'SELECT toUInt8(number) FROM system.numbers LIMIT 9000000 FORMAT RowBinary'

Establecer un rol con parámetros de consulta

Esta funcionalidad se añadió en ClickHouse 24.4.

En determinados casos, puede ser necesario establecer primero el rol concedido antes de ejecutar la propia sentencia. Sin embargo, no es posible enviar SET ROLE y la sentencia a la vez, ya que no se permiten múltiples sentencias:

curl -sS "http://localhost:8123" --data-binary "SET ROLE my_role;SELECT * FROM my_table;"

El comando anterior genera un error:

Code: 62. DB::Exception: Syntax error (Multi-statements are not allowed)

Para superar esta limitación, utilice en su lugar el parámetro de consulta role:

curl -sS "http://localhost:8123?role=my_role" --data-binary "SELECT * FROM my_table;"

Esto equivale a ejecutar SET ROLE my_role antes de la sentencia.

Además, es posible especificar varios parámetros de consulta role:

curl -sS "http://localhost:8123?role=my_role&role=my_other_role" --data-binary "SELECT * FROM my_table;"

En este caso, ?role=my_role&role=my_other_role funciona igual que ejecutar SET ROLE my_role, my_other_role antes de la sentencia.

Advertencias sobre los códigos de respuesta HTTP

Debido a las limitaciones del protocolo HTTP, un código de respuesta HTTP 200 no garantiza que una consulta se haya ejecutado correctamente.

He aquí un ejemplo:

curl -v -Ss "http://localhost:8123/?max_block_size=1&query=select+sleepEachRow(0.001),throwIf(number=2)from+numbers(5)"
*   Trying 127.0.0.1:8123...
...
< HTTP/1.1 200 OK
...
Code: 395. DB::Exception: Value passed to 'throwIf' function is non-zero: while executing 'FUNCTION throwIf(equals(number, 2) :: 1) -> throwIf(equals(number, 2))

La razón de este comportamiento es la naturaleza del protocolo HTTP. La cabecera HTTP se envía primero con un código HTTP 200, seguido del cuerpo HTTP, y luego el error se inserta en el cuerpo como texto sin formato.

Este comportamiento es independiente del formato utilizado, ya sea Native, TSV o JSON; el mensaje de error siempre aparecerá en medio del flujo de respuesta.

Puede mitigar este problema habilitando wait_end_of_query=1 (búfer de respuesta). En este caso, el envío de la cabecera HTTP se retrasa hasta que se resuelve la consulta completa. Sin embargo, esto no soluciona por completo el problema, porque el resultado debe seguir cabiendo dentro de http_response_buffer_size, y otras configuraciones, como send_progress_in_http_headers, pueden interferir con el retraso de la cabecera.

Estas excepciones en ClickHouse tienen un formato de excepción uniforme, como se muestra a continuación, independientemente del formato utilizado (p. ej., Native, TSV, JSON, etc.) cuando http_write_exception_in_output_format=0 (valor predeterminado). Esto facilita el análisis y la extracción de mensajes de error en el lado del cliente.

\r\n
__exception__\r\n
<TAG>\r\n
<error message>\r\n
<message_length> <TAG>\r\n
__exception__\r\n

Donde <TAG> es una etiqueta aleatoria de 16 bytes, la misma etiqueta enviada en la cabecera de respuesta X-ClickHouse-Exception-Tag. El <error message> es el mensaje real de la excepción (la longitud exacta puede encontrarse en <message_length>). Todo el bloque de excepción descrito anteriormente puede tener un tamaño de hasta 16 KiB.

A continuación se muestra un ejemplo en formato JSON

$ curl -v -Ss "http://localhost:8123/?max_block_size=1&query=select+sleepEachRow(0.001),throwIf(number=2)from+numbers(5)+FORMAT+JSON"
...
{
    "meta":
    [
        {
            "name": "sleepEachRow(0.001)",
            "type": "UInt8"
        },
        {
            "name": "throwIf(equals(number, 2))",
            "type": "UInt8"
        }
    ],

    "data":
    [
        {
            "sleepEachRow(0.001)": 0,
            "throwIf(equals(number, 2))": 0
        },
        {
            "sleepEachRow(0.001)": 0,
            "throwIf(equals(number, 2))": 0
        }
__exception__
dmrdfnujjqvszhav
Code: 395. DB::Exception: Value passed to 'throwIf' function is non-zero: while executing 'FUNCTION throwIf(equals(__table1.number, 2_UInt8) :: 1) -> throwIf(equals(__table1.number, 2_UInt8)) UInt8 : 0'. (FUNCTION_THROW_IF_VALUE_IS_NON_ZERO) (version 25.11.1.1)
262 dmrdfnujjqvszhav
__exception__

Aquí tienes un ejemplo similar, pero en formato CSV

$ curl -v -Ss "http://localhost:8123/?max_block_size=1&query=select+sleepEachRow(0.001),throwIf(number=2)from+numbers(5)+FORMAT+CSV"
...
<
0,0
0,0

__exception__
rumfyutuqkncbgau
Code: 395. DB::Exception: Value passed to 'throwIf' function is non-zero: while executing 'FUNCTION throwIf(equals(__table1.number, 2_UInt8) :: 1) -> throwIf(equals(__table1.number, 2_UInt8)) UInt8 : 0'. (FUNCTION_THROW_IF_VALUE_IS_NON_ZERO) (version 25.11.1.1)
262 rumfyutuqkncbgau
__exception__

Consultas con parámetros

Puede crear una consulta con parámetros y pasar sus valores mediante los parámetros de la solicitud HTTP correspondientes. Para obtener más información, consulte Consultas con parámetros para la CLI.

Ejemplo

$ curl -sS "<address>?param_id=2&param_phrase=test" -d "SELECT * FROM table WHERE int_column = {id:UInt8} and string_column = {phrase:String}"

Tabulaciones en los parámetros de URL

Los parámetros de consulta se interpretan a partir del formato "escaped". Esto tiene algunas ventajas, como la posibilidad de interpretar los valores nulos de forma inequívoca como \N. Esto significa que el carácter de tabulación debe codificarse como \t (o \ y una tabulación). Por ejemplo, lo siguiente contiene una tabulación real entre abc y 123, y la cadena de entrada se divide en dos valores:

curl -sS "http://localhost:8123" -d "SELECT splitByChar('\t', 'abc      123')"
['abc','123']

Sin embargo, si intentas codificar un carácter de tabulación real usando %09 en un parámetro de la URL, no se interpretará correctamente:

curl -sS "http://localhost:8123?param_arg1=abc%09123" -d "SELECT splitByChar('\t', {arg1:String})"
Code: 457. DB::Exception: Value abc    123 cannot be parsed as String for query parameter 'arg1' because it isn't parsed completely: only 3 of 7 bytes was parsed: abc. (BAD_QUERY_PARAMETER) (version 23.4.1.869 (official build))

Si usas parámetros de URL, tendrás que codificar \t como %5C%09. Por ejemplo:

curl -sS "http://localhost:8123?param_arg1=abc%5C%09123" -d "SELECT splitByChar('\t', {arg1:String})"
['abc','123']

Interfaz HTTP predefinida

ClickHouse admite consultas específicas a través de la interfaz HTTP. Por ejemplo, puede escribir datos en una tabla de la siguiente manera:

$ echo '(4),(5),(6)' | curl 'http://localhost:8123/?query=INSERT%20INTO%20t%20VALUES' --data-binary @-

ClickHouse también admite una Interfaz HTTP predefinida que puede ayudarle a integrarse más fácilmente con herramientas de terceros como Prometheus exporter. Veamos un ejemplo.

En primer lugar, añada esta sección a su archivo de configuración del servidor.

http_handlers se configura para contener varias rule. ClickHouse hará coincidir las solicitudes HTTP recibidas con el tipo predefinido en rule, y la primera regla que coincida ejecutará el handler. Después, ClickHouse ejecutará la consulta predefinida correspondiente si la coincidencia se realiza correctamente.

config.xmlyaml
<http_handlers>
    <rule>
        <url>/predefined_query</url>
        <methods>POST,GET</methods>
        <handler>
            <type>predefined_query_handler</type>
            <query>SELECT * FROM system.metrics LIMIT 5 FORMAT Template SETTINGS format_template_resultset = 'prometheus_template_output_format_resultset', format_template_row = 'prometheus_template_output_format_row', format_template_rows_between_delimiter = '\n'</query>
        </handler>
    </rule>
    <rule>...</rule>
    <rule>...</rule>
</http_handlers>

Ahora puede solicitar directamente la URL para obtener datos en formato Prometheus:

$ curl -v 'http://localhost:8123/predefined_query'
*   Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /predefined_query HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Tue, 28 Apr 2020 08:52:56 GMT
< Connection: Keep-Alive
< Content-Type: text/plain; charset=UTF-8
< X-ClickHouse-Server-Display-Name: i-mloy5trc
< Transfer-Encoding: chunked
< X-ClickHouse-Query-Id: 96fe0052-01e6-43ce-b12a-6b7370de6e8a
< X-ClickHouse-Format: Template
< X-ClickHouse-Timezone: Asia/Shanghai
< Keep-Alive: timeout=10
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334","memory_usage":"8451671"}
<
# HELP "Query" "Number of executing queries"
# TYPE "Query" counter
"Query" 1

# HELP "Merge" "Number of executing background merges"
# TYPE "Merge" counter
"Merge" 0

# HELP "PartMutation" "Number of mutations (ALTER DELETE/UPDATE)"
# TYPE "PartMutation" counter
"PartMutation" 0

# HELP "ReplicatedFetch" "Number of data parts being fetched from replica"
# TYPE "ReplicatedFetch" counter
"ReplicatedFetch" 0

# HELP "ReplicatedSend" "Number of data parts being sent to replicas"
# TYPE "ReplicatedSend" counter
"ReplicatedSend" 0

* Connection #0 to host localhost left intact

* Connection #0 to host localhost left intact

Las opciones de configuración de http_handlers funcionan de la siguiente manera.

rule permite configurar los siguientes parámetros:

  • method
  • headers
  • url
  • full_url
  • handler

Cada uno de ellos se describe a continuación:

  • method se utiliza para hacer coincidir la parte correspondiente al método de la solicitud HTTP. method cumple por completo la definición de [method] (https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) del protocolo HTTP. Es una configuración opcional. Si no está definida en el archivo de configuración, no se compara la parte del método de la solicitud HTTP.

  • url se utiliza para hacer coincidir la parte de la URL (ruta y cadena de consulta) de la solicitud HTTP. Si url tiene el prefijo regex:, se esperan expresiones regulares de RE2. Es una configuración opcional. Si no está definida en el archivo de configuración, no se compara la parte de la URL de la solicitud HTTP.

  • full_url es igual que url, pero incluye la URL completa, es decir, schema://host:port/path?query_string. Ten en cuenta que ClickHouse no admite "virtual hosts", por lo que host es una dirección IP (y no el valor del encabezado Host).

  • empty_query_string - garantiza que no haya ninguna cadena de consulta (?query_string) en la solicitud

  • headers se utilizan para hacer coincidir la parte de los encabezados de la solicitud HTTP. Es compatible con las expresiones regulares de RE2. Es una configuración opcional. Si no está definida en el archivo de configuración, no se compara la parte de los encabezados de la solicitud HTTP.

  • handler contiene la parte principal del procesamiento.

    Puede tener el siguiente type:

    Y los siguientes parámetros:

    • query — úselo con el tipo predefined_query_handler; ejecuta la consulta cuando se llama al controlador.
    • query_param_name — úselo con el tipo dynamic_query_handler; extrae y ejecuta el valor correspondiente a query_param_name en los parámetros de la solicitud HTTP.
    • status — úselo con el tipo static; código de estado de la respuesta.
    • content_type — úselo con cualquier tipo; content-type de la respuesta.
    • http_response_headers — úselo con cualquier tipo; mapa de encabezados de la respuesta. También puede usarse para establecer el tipo de contenido.
    • response_content — úselo con el tipo static; contenido de la respuesta enviado al cliente; al usar el prefijo 'file://' o 'config://', obtiene el contenido del archivo o de la configuración y lo envía al cliente.
    • user - usuario con el que se ejecutará la consulta (el usuario predeterminado es default). Nota: no es necesario especificar la contraseña de este usuario.

A continuación se describen los métodos de configuración para los distintos type.

predefined_query_handler

predefined_query_handler admite la configuración de los valores Settings y query_params. Puede configurar query para el tipo predefined_query_handler.

El valor de query es una consulta predefinida de predefined_query_handler que ClickHouse ejecuta cuando coincide una solicitud HTTP, y se devuelve el resultado de la consulta. Es una configuración obligatoria.

El siguiente ejemplo define los valores de las configuraciones max_threads y max_final_threads, y luego consulta la tabla del sistema para comprobar si estas configuraciones se han establecido correctamente.

Por ejemplo:

<http_handlers>
    <rule>
        <url><![CDATA[regex:/query_param_with_url/(?P<name_1>[^/]+)]]></url>
        <methods>GET</methods>
        <headers>
            <XXX>TEST_HEADER_VALUE</XXX>
            <PARAMS_XXX><![CDATA[regex:(?P<name_2>[^/]+)]]></PARAMS_XXX>
        </headers>
        <handler>
            <type>predefined_query_handler</type>
            <query>
                SELECT name, value FROM system.settings
                WHERE name IN ({name_1:String}, {name_2:String})
            </query>
        </handler>
    </rule>
    <defaults/>
</http_handlers>
curl -H 'XXX:TEST_HEADER_VALUE' -H 'PARAMS_XXX:max_final_threads' 'http://localhost:8123/query_param_with_url/max_threads?max_threads=1&max_final_threads=2'
max_final_threads    2
max_threads    1

Parámetro virtual _request_body

Además de los parámetros de URL, los encabezados y los parámetros de consulta, predefined_query_handler admite un parámetro virtual especial, _request_body. Contiene el cuerpo de la solicitud HTTP sin procesar como una cadena. Esto permite crear API REST flexibles que pueden aceptar formatos de datos arbitrarios y procesarlos dentro de las consultas.

Por ejemplo, puede usar _request_body para implementar un endpoint REST que acepte datos JSON en una solicitud POST y los inserte en una tabla:

<http_handlers>
    <rule>
        <methods>POST</methods>
        <url>/api/events</url>
        <handler>
            <type>predefined_query_handler</type>
            <query>
                INSERT INTO events (id, data)
                SELECT {id:UInt32}, {_request_body:String}
            </query>
        </handler>
    </rule>
    <defaults/>
</http_handlers>

A continuación, puede enviar datos a este endpoint:

curl -X POST 'http://localhost:8123/api/events?id=123' \
  -H 'Content-Type: application/json' \
  -d '{"user": "john", "action": "login", "timestamp": "2024-01-01T10:00:00Z"}'

dynamic_query_handler

En dynamic_query_handler, la consulta se escribe como parámetro de la solicitud HTTP. La diferencia es que, en predefined_query_handler, la consulta se escribe en el archivo de configuración. query_param_name puede configurarse en dynamic_query_handler.

ClickHouse extrae y ejecuta el valor correspondiente a query_param_name en la URL de la solicitud HTTP. El valor predeterminado de query_param_name es /query . Es una configuración opcional. Si no hay ninguna definición en el archivo de configuración, el parámetro no se pasa.

Para probar esta funcionalidad, el siguiente ejemplo define los valores de max_threads y max_final_threads, y consulta si la configuración se aplicó correctamente.

Ejemplo:

<http_handlers>
    <rule>
    <headers>
        <XXX>TEST_HEADER_VALUE_DYNAMIC</XXX>    </headers>
    <handler>
        <type>dynamic_query_handler</type>
        <query_param_name>query_param</query_param_name>
    </handler>
    </rule>
    <defaults/>
</http_handlers>
curl  -H 'XXX:TEST_HEADER_VALUE_DYNAMIC'  'http://localhost:8123/own?max_threads=1&max_final_threads=2&param_name_1=max_threads&param_name_2=max_final_threads&query_param=SELECT%20name,value%20FROM%20system.settings%20where%20name%20=%20%7Bname_1:String%7D%20OR%20name%20=%20%7Bname_2:String%7D'
max_threads 1
max_final_threads   2

static

static puede devolver content_type, código de estado y response_content. response_content puede devolver el contenido especificado.

Por ejemplo, para devolver un mensaje "Say Hi!":

<http_handlers>
        <rule>
            <methods>GET</methods>
            <headers><XXX>xxx</XXX></headers>
            <url>/hi</url>
            <handler>
                <type>static</type>
                <status>402</status>
                <content_type>text/html; charset=UTF-8</content_type>
                <http_response_headers>
                    <Content-Language>en</Content-Language>
                    <X-My-Custom-Header>43</X-My-Custom-Header>
                </http_response_headers>
                <response_content>Say Hi!</response_content>
            </handler>
        </rule>
        <defaults/>
</http_handlers>

http_response_headers se puede usar para establecer el tipo de contenido en lugar de content_type.

<http_handlers>
        <rule>
            <methods>GET</methods>
            <headers><XXX>xxx</XXX></headers>
            <url>/hi</url>
            <handler>
                <type>static</type>
                <status>402</status>
                #begin-highlight
                <http_response_headers>
                    <Content-Type>text/html; charset=UTF-8</Content-Type>
                    <Content-Language>en</Content-Language>
                    <X-My-Custom-Header>43</X-My-Custom-Header>
                </http_response_headers>
                #end-highlight
                <response_content>Say Hi!</response_content>
            </handler>
        </rule>
        <defaults/>
</http_handlers>
curl -vv  -H 'XXX:xxx' 'http://localhost:8123/hi'
*   Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /hi HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
> XXX:xxx
>
< HTTP/1.1 402 Payment Required
< Date: Wed, 29 Apr 2020 03:51:26 GMT
< Connection: Keep-Alive
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Keep-Alive: timeout=10
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334","memory_usage":"8451671"}
<
* Connection #0 to host localhost left intact
Say Hi!%

Encuentre el contenido de la configuración enviada al cliente.

<get_config_static_handler><![CDATA[<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>]]></get_config_static_handler>

<http_handlers>
        <rule>
            <methods>GET</methods>
            <headers><XXX>xxx</XXX></headers>
            <url>/get_config_static_handler</url>
            <handler>
                <type>static</type>
                <response_content>config://get_config_static_handler</response_content>
            </handler>
        </rule>
</http_handlers>
$ curl -v  -H 'XXX:xxx' 'http://localhost:8123/get_config_static_handler'
*   Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /get_config_static_handler HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
> XXX:xxx
>
< HTTP/1.1 200 OK
< Date: Wed, 29 Apr 2020 04:01:24 GMT
< Connection: Keep-Alive
< Content-Type: text/plain; charset=UTF-8
< Transfer-Encoding: chunked
< Keep-Alive: timeout=10
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334","memory_usage":"8451671"}
<
* Connection #0 to host localhost left intact
<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>%

Para encontrar el contenido del archivo enviado al cliente:

<http_handlers>
        <rule>
            <methods>GET</methods>
            <headers><XXX>xxx</XXX></headers>
            <url>/get_absolute_path_static_handler</url>
            <handler>
                <type>static</type>
                <content_type>text/html; charset=UTF-8</content_type>
                <http_response_headers>
                    <ETag>737060cd8c284d8af7ad3082f209582d</ETag>
                </http_response_headers>
                <response_content>file:///absolute_path_file.html</response_content>
            </handler>
        </rule>
        <rule>
            <methods>GET</methods>
            <headers><XXX>xxx</XXX></headers>
            <url>/get_relative_path_static_handler</url>
            <handler>
                <type>static</type>
                <content_type>text/html; charset=UTF-8</content_type>
                <http_response_headers>
                    <ETag>737060cd8c284d8af7ad3082f209582d</ETag>
                </http_response_headers>
                <response_content>file://./relative_path_file.html</response_content>
            </handler>
        </rule>
</http_handlers>
$ user_files_path='/var/lib/clickhouse/user_files'
$ sudo echo "<html><body>Relative Path File</body></html>" > $user_files_path/relative_path_file.html
$ sudo echo "<html><body>Absolute Path File</body></html>" > $user_files_path/absolute_path_file.html
$ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_absolute_path_static_handler'
*   Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /get_absolute_path_static_handler HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
> XXX:xxx
>
< HTTP/1.1 200 OK
< Date: Wed, 29 Apr 2020 04:18:16 GMT
< Connection: Keep-Alive
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Keep-Alive: timeout=10
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334","memory_usage":"8451671"}
<
<html><body>Absolute Path File</body></html>
* Connection #0 to host localhost left intact
$ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_relative_path_static_handler'
*   Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /get_relative_path_static_handler HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
> XXX:xxx
>
< HTTP/1.1 200 OK
< Date: Wed, 29 Apr 2020 04:18:31 GMT
< Connection: Keep-Alive
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Keep-Alive: timeout=10
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334","memory_usage":"8451671"}
<
<html><body>Relative Path File</body></html>
* Connection #0 to host localhost left intact

redirect

redirect realizará una redirección 302 a location

Por ejemplo, así puedes añadir automáticamente set user a play en ClickHouse play:

<clickhouse>
    <http_handlers>
        <rule>
            <methods>GET</methods>
            <url>/play</url>
            <handler>
                <type>redirect</type>
                <location>/play?user=play</location>
            </handler>
        </rule>
    </http_handlers>
</clickhouse>

Encabezados de respuesta HTTP

ClickHouse le permite configurar encabezados de respuesta HTTP personalizados que pueden aplicarse a cualquier tipo de handler configurable. Estos encabezados pueden definirse mediante la configuración http_response_headers, que acepta pares clave-valor que representan los nombres de los encabezados y sus valores. Esta funcionalidad resulta especialmente útil para implementar encabezados de seguridad personalizados, políticas CORS o cualquier otro requisito relacionado con encabezados HTTP en toda la interfaz HTTP de ClickHouse.

Por ejemplo, puede configurar encabezados para:

  • Endpoints de consulta normales
  • Web UI
  • Comprobación de estado.

También es posible especificar common_http_response_headers. Estos se aplicarán a todos los handlers HTTP definidos en la configuración.

Los encabezados se incluirán en la respuesta HTTP de cada handler configurado.

En el ejemplo siguiente, cada respuesta del servidor contendrá dos encabezados personalizados: X-My-Common-Header y X-My-Custom-Header.

<clickhouse>
    <http_handlers>
        <common_http_response_headers>
            <X-My-Common-Header>Common header</X-My-Common-Header>
        </common_http_response_headers>
        <rule>
            <methods>GET</methods>
            <url>/ping</url>
            <handler>
                <type>ping</type>
                <http_response_headers>
                    <X-My-Custom-Header>Custom indeed</X-My-Custom-Header>
                </http_response_headers>
            </handler>
        </rule>
    </http_handlers>
</clickhouse>

Respuesta JSON/XML válida en caso de excepción durante HTTP streaming

Mientras una consulta se ejecuta a través de HTTP, puede producirse una excepción cuando parte de los datos ya se ha enviado. Normalmente, la excepción se envía al client en texto sin formato. Esto puede ocurrir incluso si se ha usado un formato de datos específico para la salida, y hacer que la salida deje de ser válida con respecto al formato especificado. Para evitarlo, puede usar la opción http_write_exception_in_output_format (desactivada de forma predeterminada), que indica a ClickHouse que escriba la excepción en el formato especificado (actualmente compatible con los formatos XML y JSON*).

Ejemplos:

$ curl 'http://localhost:8123/?query=SELECT+number,+throwIf(number>3)+from+system.numbers+format+JSON+settings+max_block_size=1&http_write_exception_in_output_format=1'
{
    "meta":
    [
        {
            "name": "number",
            "type": "UInt64"
        },
        {
            "name": "throwIf(greater(number, 2))",
            "type": "UInt8"
        }
    ],

    "data":
    [
        {
            "number": "0",
            "throwIf(greater(number, 2))": 0
        },
        {
            "number": "1",
            "throwIf(greater(number, 2))": 0
        },
        {
            "number": "2",
            "throwIf(greater(number, 2))": 0
        }
    ],

    "rows": 3,

    "exception": "Code: 395. DB::Exception: Value passed to 'throwIf' function is non-zero: while executing 'FUNCTION throwIf(greater(number, 2) :: 2) -> throwIf(greater(number, 2)) UInt8 : 1'. (FUNCTION_THROW_IF_VALUE_IS_NON_ZERO) (version 23.8.1.1)"
}
$ curl 'http://localhost:8123/?query=SELECT+number,+throwIf(number>2)+from+system.numbers+format+XML+settings+max_block_size=1&http_write_exception_in_output_format=1'
<?xml version='1.0' encoding='UTF-8' ?>
<result>
    <meta>
        <columns>
            <column>
                <name>number</name>
                <type>UInt64</type>
            </column>
            <column>
                <name>throwIf(greater(number, 2))</name>
                <type>UInt8</type>
            </column>
        </columns>
    </meta>
    <data>
        <row>
            <number>0</number>
            <field>0</field>
        </row>
        <row>
            <number>1</number>
            <field>0</field>
        </row>
        <row>
            <number>2</number>
            <field>0</field>
        </row>
    </data>
    <rows>3</rows>
    <exception>Code: 395. DB::Exception: Value passed to 'throwIf' function is non-zero: while executing 'FUNCTION throwIf(greater(number, 2) :: 2) -> throwIf(greater(number, 2)) UInt8 : 1'. (FUNCTION_THROW_IF_VALUE_IS_NON_ZERO) (version 23.8.1.1)</exception>
</result>
Navigation