Conexión
El siguiente ejemplo, que devuelve la versión del servidor, muestra cómo conectarse a ClickHouse, suponiendo que ClickHouse no está protegido y que se puede acceder con el usuariodefault.
Tenga en cuenta que usamos el puerto nativo predeterminado para conectarnos.
conn de ClickHouse ya se ha creado y está disponible.
Ejecución
Se pueden ejecutar sentencias arbitrarias mediante el métodoExec. Esto resulta útil para DDL y sentencias simples. No debe usarse para inserciones de gran volumen ni para iteraciones sobre consultas.
Inserción por lotes
Para insertar un gran número de filas, el cliente ofrece semántica de lotes. Para ello, es necesario preparar un lote al que se puedan añadir filas. Finalmente, se envía mediante el métodoSend(). Los lotes se mantienen en memoria hasta que se ejecuta Send.
Se recomienda llamar a Close en el lote para evitar fugas de conexiones. Esto puede hacerse mediante la palabra clave defer después de preparar el lote. Así se limpiará la conexión si nunca se llega a llamar a Send. Ten en cuenta que esto hará que aparezcan 0 inserciones de filas en el registro de consultas si no se añadió ninguna fila.
Columnas efímeras
Las columnas efímeras son columnas de solo escritura que existen únicamente durante la inserción: no se almacenan ni se pueden seleccionar. Son útiles para calcular valores de columnas derivadas en el momento de la inserción.Consultar filas
Puede consultar una sola fila con el métodoQueryRow u obtener un cursor para iterar sobre un conjunto de resultados con Query. Mientras que el primero acepta un destino en el que serializar los datos, el segundo requiere llamar a Scan en cada fila.
SELECT; de forma predeterminada, en el caso de un SELECT * se utilizará el orden de declaración de las columnas, como se muestra arriba.
Al igual que en la inserción, el método Scan requiere que las variables de destino sean de un tipo adecuado. De nuevo, se busca ofrecer flexibilidad, convirtiendo tipos cuando sea posible, siempre que no haya pérdida de precisión; por ejemplo, el ejemplo anterior muestra una columna UUID leída en una variable de tipo string. Para obtener una lista completa de los tipos de Go compatibles con cada tipo de columna, consulte Type Conversions.
Por último, tenga en cuenta la posibilidad de pasar un Context a los métodos Query y QueryRow. Esto puede usarse para configuraciones a nivel de consulta; consulte Using Context para obtener más detalles.
Insert asíncrono
Las inserciones asíncronas son compatibles mediante el método Async. Esto permite al usuario especificar si el cliente debe esperar a que el servidor complete la inserción o si debe responder una vez recibidos los datos. Esto controla de forma efectiva el parámetro wait_for_async_insert.Inserción columnar
Las inserciones pueden hacerse en formato columnar. Esto puede aportar ventajas de rendimiento si los datos ya están organizados de esta forma, ya que evita tener que convertirlos en filas.Uso de structs
Para los usuarios, los structs de Golang proporcionan una representación lógica de una fila de datos en ClickHouse. Para ayudar con esto, la interfaz nativa proporciona varias funciones prácticas.Select con serialización
El método Select permite convertir un conjunto de filas de respuesta en un slice de structs con una sola llamada.Scan struct
ScanStruct permite mapear una sola fila de una consulta a una struct.
Añadir struct
AppendStruct permite añadir una struct a un lote existente e interpretarla como una fila completa. Para ello, las columnas de la struct deben coincidir con la tabla tanto en nombre como en tipo. Aunque todas las columnas deben tener un campo equivalente en la struct, puede que algunos campos de la struct no tengan una columna equivalente. Estos simplemente se ignorarán.
Parámetros de consulta del lado del servidor
Los parámetros de consulta del lado del servidor de ClickHouse utilizan marcadores de posición tipados con el formato{name:Type}. La consulta y los valores de los parámetros se envían por separado, de modo que los valores de los parámetros no se interpolan en el texto SQL.
Con la API de ClickHouse, pase los parámetros mediante el contexto de la consulta:
clickhouse.Named:
clickhouse.Named también funciona con la sintaxis de vinculación @name del lado del cliente; lo que determina el mecanismo es el marcador de posición que se usa en la consulta ({name:Type} o @name).
Valores String y secuencias de escape
La forma en que se interpreta un valor de cadena depende de cómo se proporcione.clickhouse.Named (o sql.Named) con un valor string/*string o []byte/*[]byte trata el valor de Go como el valor literal del parámetro. El controlador escapa automáticamente los caracteres de control, de modo que el valor hace el viaje de ida y vuelta byte a byte, sin alteraciones, en ambos protocolos. Un salto de línea o una tabulación reales en el valor no suponen ningún problema:
clickhouse.Parameters / WithParameters siempre contiene texto de parámetro ya serializado en el formato Escaped de ClickHouse. No se escapa automáticamente. ClickHouse decodifica las secuencias de escape con barra invertida al analizar el parámetro: \n (salto de línea), \t (tabulación), \r (retorno de carro), \0 (byte nulo) y \\ (una barra invertida literal). \N es el marcador NULL que representa el valor completo en tipos Nullable.
Go procesa los literales de cadena interpretados ("...") antes de que clickhouse-go los reciba, mientras que los literales de cadena sin procesar (`...`) conservan las barras invertidas. Para Parameters, escriba el texto del parámetro de la siguiente manera:
No use
"line 1\nline 2" ni "column 1\tcolumn 2" al construir Parameters. Esos literales de Go ya contienen un salto de línea o una tabulación reales. En el formato Escaped de ClickHouse, los bytes reales de salto de línea y tabulación actúan como delimitadores de campos, por lo que el servidor rechaza el parámetro al no poder analizarlo por completo. Si quiere que una cadena de Go se trate como un valor literal, use Named en su lugar.
Los valores de parámetro no son literales SQL: para un String de nivel superior pasado mediante Named, indique el valor sin comillas SQL; use hello, no 'hello', ya que esas comillas pasarían a formar parte del valor. Los tipos compuestos siguen usando su sintaxis de texto, por ejemplo ['a', 'b'] para un Array(String), que también puede pasar mediante Named siempre que el texto no contenga escapes con barra invertida ni caracteres de control sin procesar. Si el texto compuesto requiere secuencias de escape \' para valores de cadena anidados, páselo mediante Parameters.
Ejemplo completo de la API nativa
Vinculación de parámetros
El cliente admite la vinculación de parámetros en los métodosExec, Query y QueryRow. Como se muestra en el siguiente ejemplo, se admite el uso de parámetros con nombre, numerados y posicionales. A continuación se muestran ejemplos de cada uno.
Casos especiales
De forma predeterminada, los slices se expanden en una lista de valores separados por comas si se pasan como parámetro a una consulta. Si necesita que un conjunto de valores se inserte entre corchetes[ ], debe usar ArraySet.
Si se requieren grupos/tuplas, entre paréntesis ( ), por ejemplo, para usarlos con operadores IN, puede usar GroupSet. Esto resulta especialmente útil cuando se requieren varios grupos, como se muestra en el ejemplo siguiente.
Por último, los campos DateTime64 requieren precisión para garantizar que los parámetros se representen correctamente. Sin embargo, el cliente desconoce el nivel de precisión del campo, por lo que el usuario debe proporcionarlo. Para facilitarlo, proporcionamos el parámetro DateNamed.
Uso del contexto
Los contextos de Go proporcionan una forma de pasar fechas límite, señales de cancelación y otros valores asociados a una solicitud a través de los límites de la API. Todos los métodos de una conexión aceptan un contexto como primer parámetro. Aunque en los ejemplos anteriores se usócontext.Background(), puede usar esta capacidad para pasar configuraciones y fechas límite, así como para cancelar consultas.
Pasar un contexto creado con withDeadline permite establecer límites de tiempo de ejecución en las consultas. Tenga en cuenta que se trata de un instante absoluto y que su vencimiento solo liberará la conexión y enviará una señal de cancelación a ClickHouse. Como alternativa, puede usarse WithCancel para cancelar una consulta explícitamente.
Los auxiliares clickhouse.WithQueryID y clickhouse.WithQuotaKey permiten especificar un identificador de consulta y una clave de cuota. Los identificadores de consulta pueden ser útiles para rastrear consultas en los registros y con fines de cancelación. Se puede usar una clave de cuota para imponer límites al uso de ClickHouse en función de un valor de clave único; consulte Quotas Management para obtener más información.
También puede usar el contexto para asegurarse de que una configuración solo se aplique a una consulta específica, en lugar de a toda la conexión, como se muestra en Connection Settings.
Por último, puede controlar el tamaño del búfer de bloques mediante clickhouse.WithBlockSize. Esto anula la configuración de nivel de conexión BlockBufferSize y controla el número máximo de bloques que se decodifican y se mantienen en memoria en un momento dado. Los valores más altos pueden permitir una mayor paralelización, a costa de un mayor uso de memoria.
A continuación se muestran ejemplos de lo anterior.
Información de Progress, Profile y Log
Se puede solicitar información de Progress, Profile y Log en las consultas. La información de Progress muestra estadísticas sobre la cantidad de filas y bytes leídos y procesados en ClickHouse. En cambio, la información de Profile ofrece un resumen de los datos devueltos al cliente, incluidos los totales de bytes (sin comprimir), filas y bloques. Por último, la información de Log proporciona estadísticas sobre los hilos, por ejemplo, el uso de memoria y la velocidad de procesamiento de los datos. Para obtener esta información, es necesario que el usuario use Context, al que puede pasar funciones de callback.Escaneo dinámico
Puede que necesite leer tablas cuyo esquema o tipo de los campos devueltos se desconozca. Esto es habitual cuando se realiza análisis de datos ad hoc o se desarrollan herramientas genéricas. Para ello, la información sobre los tipos de las columnas está disponible en las respuestas a las consultas. Esto puede usarse con la reflexión de Go para crear instancias en tiempo de ejecución de variables con los tipos correctos que pueden pasarse a Scan.Tablas externas
Las tablas externas permiten al cliente enviar datos a ClickHouse junto con una consulta SELECT. Estos datos se colocan en una tabla temporal y pueden usarse en la propia consulta para evaluarlos. Para enviar datos externos al cliente con una consulta, el usuario debe crear una tabla externa medianteext.NewTable antes de pasarla a través del contexto.
OpenTelemetry
ClickHouse admite la propagación del contexto de trazas tanto en los transportes TCP como HTTP. Cuando se usa TCP, el cliente serializa el span en el protocolo binario nativo. Usaclickhouse.WithSpan para adjuntar un span a una consulta mediante el contexto.
Limitación del transporte HTTPAunque el servidor de ClickHouse acepta las cabeceras HTTP estándar
traceparent / tracestate, el transporte HTTP de clickhouse-go actualmente no las envía, por lo que WithSpan no tiene efecto en HTTP. Como alternativa, puedes configurar manualmente la cabecera mediante HttpHeaders en las opciones de conexión.