> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> Códec de Rust compilado y opcional para ClickHouse Connect

# Códec nativo de Rust

ClickHouse Connect puede decodificar los resultados de las consultas y codificar los inserts con un códec de Rust compilado en lugar de la implementación predeterminada en Python y Cython. El códec de Rust se aplica únicamente al tráfico `FORMAT Native` gestionado por el client, lo que abarca `query`, `query_np`, `query_df`, sus variantes de streaming por bloques y por filas, y los inserts, incluido `insert_df`. Los métodos de Arrow usan `FORMAT Arrow` y no se ven afectados, al igual que las consultas sin procesar, los inserts sin procesar y los formatos que no son Native.

El códec es experimental y de uso opcional. El códec de Python sigue siendo el predeterminado.

## Instalación

El códec compilado se distribuye como un paquete wheel independiente llamado `clickhouse-connect-core`, que proporciona el módulo de extensión `_ch_core`. Instale el códec junto con las integraciones que use su aplicación:

```bash theme={null}
pip install "clickhouse-connect[rust]"         # Python rows and Native inserts
pip install "clickhouse-connect[rust,numpy]"   # NumPy results
pip install "clickhouse-connect[rust,pandas]"  # Pandas results and inserts
```

Se publican wheels del núcleo para CPython 3.10 a 3.14 y para CPython 3.14t free-threaded en Linux, macOS y Windows. En Python free-threaded, importar la extensión del núcleo no vuelve a habilitar el GIL.

La salida estándar de NumPy y Pandas en Rust no requiere PyArrow ni ningún otro paquete de Arrow. Esto incluye `query_np`, `query_df`, sus variantes de streaming y `query(..., use_numpy=True)`. Las consultas de NumPy no requieren Pandas. Agregue el extra `async` para usar el Client asíncrono.

PyArrow sigue siendo necesario para los métodos de Arrow y para el almacenamiento de Pandas basado en Arrow. Instale el extra `arrow` para usar estas funcionalidades:

```bash theme={null}
pip install "clickhouse-connect[rust,pandas,arrow]"
```

La salida extendida de cadenas de Pandas sigue la opción `mode.string_storage` de Pandas. Cuando PyArrow está instalado, las cadenas usan la conversión de Arrow existente, con validación completa de UTF-8, con cualquiera de los dos backends de almacenamiento. Sin PyArrow, el driver usa la conversión de objetos de Rust y el almacenamiento predeterminado de Pandas usa cadenas de Python. Si se solicita explícitamente el almacenamiento de cadenas de Arrow sin PyArrow, se lanza un error de dependencia. El UTF-8 no válido mantiene la representación hexadecimal existente con cualquiera de los dos backends de almacenamiento.

El códec, su empaquetado y su conjunto de dependencias son experimentales. La conversión directa de búfer ahora admite columnas no Nullable de enteros de 8 a 64 bits, Float32/64, Boolean, BFloat16, Interval, Date, Date32, DateTime y DateTime64. Las columnas escalares Time y Time64, incluidos los valores Nullable, también usan búferes directos, al igual que BFloat16 Nullable y la salida extendida de Pandas de enteros, flotantes e Interval Nullable. BFloat16 conserva la salida float32 y su política actual de valores faltantes Float32 de Pandas. Los valores Interval siguen siendo recuentos con signo en su unidad declarada. La conversión temporal conserva las unidades declaradas y las reglas de zona horaria existentes. Los alias Nullable de SimpleAggregateFunction de Time64 ahora devuelven duraciones correctas y NaT para los valores NULL. Las columnas escalares Nullable DateTime64(9) también usan búferes para preservar los nanosegundos en la salida de NumPy y Pandas. Las demás fechas y marcas de tiempo Nullable mantienen sus rutas de conversión de objetos.

Los arrays de Time/Time64, incluidos los arrays anidados y las hojas Nullable, y LowCardinality(Time), incluidos los valores Nullable, también usan búferes directos. Su anidamiento, sus unidades de duración y su representación de valores nulos no cambian. LowCardinality(Time64) sigue sin ser compatible con el núcleo de Rust.

Para las columnas escalares Nullable DateTime64(9), `query_df` y `query_df_stream` preservan los nueve dígitos fraccionarios, incluso a través de alias de SimpleAggregateFunction. En Pandas 3, las columnas de fecha y hora de la salida predeterminada ahora usan unidades de nanosegundos en lugar de microsegundos. La inferencia actual del dtype object para bloques compuestos íntegramente por NULL no cambia. Si una zona horaria con nombre situara un valor fuera del rango de nanosegundos de Pandas, esa columna mantiene su conversión de objetos y su comportamiento de rango anteriores.

Para estas columnas, los campos de objeto de `query_np` y `query_np_stream` ahora contienen celdas `numpy.datetime64` en lugar de celdas `datetime` de Python, con `None` para los NULL de SQL. Los valores de zonas con nombre usan ticks UTC sin metadata de zona horaria, igual que el códec de Python. Así se preservan los nanosegundos sin necesidad de Pandas. Use `query_df` si necesita marcas de tiempo con zona horaria. Los demás tipos de celdas temporales Nullable de NumPy no cambian.

Las consultas escalares DateTime64 de NumPy y Pandas rechazan con `ProgrammingError` las precisiones distintas de 0, 3, 6 y 9, incluidas las columnas Nullable y los alias de SimpleAggregateFunction.

Si se selecciona un códec de Rust y el módulo compilado no está instalado, la creación del Client lanza un `NotSupportedError` que indica este comando de instalación.

## Habilitar el códec

Seleccione el códec con la opción de client `native_codec`:

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client(host="localhost", native_codec="rust")
```

Valores aceptados:

| Value | Comportamiento |
| - | - |
| `python` | Valor predeterminado. El códec existente de Python y Cython. |
| `rust` | Da preferencia al códec de Rust. Las queries con opciones no admitidas y los inserts con tipos no admitidos se redirigen al códec de Python. |
| `rust_strict` | Exige el códec de Rust. Las opciones y los tipos no admitidos generan un error en lugar de redirigirse. |

El valor predeterminado también puede definirse mediante el common setting `native_codec` o la environment variable `CLICKHOUSE_CONNECT_NATIVE_CODEC`. El orden de precedencia es: primero el keyword argument del client, luego el common setting y, por último, la environment variable.

Esta opción se ignora en los clients con `interface="chdb"`, que siempre usan el códec de Python.

## Cuándo usar el códec de Rust

El códec de Rust resulta más útil para resultados de DataFrame grandes con tipos de texto, de contenedor y complejos, como `String`, `LowCardinality`, `Map`, `Array`, `JSON`, `Decimal` y `UUID`. También puede beneficiar a streams de bloques grandes de filas y columnas, a cargas de trabajo con consultas concurrentes y a inserciones masivas.

En resultados pequeños y consultas limitadas por la red, la diferencia puede ser mínima. Los resultados numéricos planos ya utilizan rutas masivas eficientes en el códec de Python, por lo que el beneficio también puede ser menor.

Los búferes directos evitan arrays intermedios de Arrow para los tipos compatibles. El ensamblado final de resultados de NumPy y Pandas aún puede reservar memoria y copiar datos, por lo que esto no hace que todos los resultados de consultas sean zero-copy.

Sin PyArrow, la conversión de cadenas en Rust construye objetos de cadena de Python a partir de cada bloque decodificado. Con los tamaños de bloque predeterminados, el pico de memoria para resultados grandes de tipo String es similar al del códec de Python. Los bloques muy grandes, como un único bloque que contiene un millón de filas, mantienen en memoria todo el bloque decodificado mientras se construyen sus cadenas y pueden alcanzar un pico de memoria mayor que el del códec de Python. Para resultados grandes de Pandas con `StringDtype`, instala el extra `arrow` y usa el almacenamiento de cadenas de Arrow. Pandas 3 selecciona el almacenamiento de Arrow de forma predeterminada cuando PyArrow está instalado. Pandas 2 requiere `pd.options.mode.string_storage = "pyarrow"`.

Las llamadas a `query()` almacenadas temporalmente en el búfer sobre resultados muy anchos o totalmente numéricos pueden ser, por ahora, más lentas y consumir más memoria máxima con el códec de Rust. Para esas cargas de trabajo, es preferible usar `query_df`, `query_row_block_stream` o `query_column_block_stream`. Para NumPy y Pandas, `query_np_stream` y `query_df_stream` también pueden reducir el pico de memoria. Procesa y libera cada bloque en lugar de acumular todo el stream. El uso de memoria sigue dependiendo del tamaño de cada bloque, por lo que hacer streaming de un único bloque grande no ofrece la misma ventaja.

Haz un benchmark de tu propia carga de trabajo antes de adoptar el códec. Usa `native_codec="rust_strict"` mientras mides, de modo que una opción no soportada o una dependencia faltante lance un error en lugar de redirigir silenciosamente la consulta a Python.

## Reglas de fallback

Las decisiones de fallback se toman antes de leer o enviar ningún byte, por lo que nunca se produce un cambio de códec a mitad del stream. En las queries, la elección ocurre antes de consumir el response body. En los inserts, el codificador de Rust solo se selecciona cuando todos los tipos de columna son compatibles; de lo contrario, todo el insert se ejecuta con el códec de Python.

Cuando `naive_datetime_insert="server"` está activo, `rust` deriva al códec de Python cualquier insert que contenga alguna columna `DateTime` o `DateTime64`, de modo que se aplique el timezone declarado de la columna o el server timezone. `rust_strict` rechaza esa combinación. El modo predeterminado `naive_datetime_insert="local"` sigue utilizando el codificador de Rust.

Las queries de metadata internas del driver, incluidas las sentencias de reflection del dialect de SQLAlchemy, siempre usan el códec de Python, de forma silenciosa, en todos los modos.

Los payloads Native malformados que detecta el códec de Rust generan `DataError`.

## Control de versiones

`clickhouse-connect-core` se versiona de forma independiente de `clickhouse-connect`. El extra `rust` requiere `clickhouse-connect-core>=0.2.1,<0.3`. El driver comprueba tanto la versión de la API de vinculación como la capacidad de búfer de columnas cuando se selecciona un códec de Rust. El wheel publicado de core 0.2.0 no incluye la capacidad de búfer de columnas. Si el wheel instalado es incompatible, la creación del Client lanza un `NotSupportedError` tanto para `rust` como para `rust_strict`, con este comando de upgrade:

```bash theme={null}
pip install --upgrade clickhouse-connect-core
```

Las correcciones y las mejoras del rendimiento en el códec compilado se publican como versiones de `clickhouse-connect-core` y pueden incorporarse actualizando a un wheel de core compatible. Los cambios en la integración de Rust del driver requieren actualizar `clickhouse-connect`.

## Diferencias de comportamiento conocidas

El códec de Rust busca la paridad celda a celda con el códec de Python. Se conocen las siguientes diferencias.

* Los resultados de `query_np` y `query_df` para columnas `Variant` contienen objetos Python simples en lugar de valores escalares de numpy. Los valores son iguales, pero los tipos de celda difieren.
* Los valores `Dynamic` que contienen `Time64` se materializan como `datetime.timedelta` en los resultados de `query_np` y `query_df` de Rust. Con las escalas 0, 3, 6 y 9, los valores coinciden con las celdas `numpy.timedelta64` del códec de Python, pero los tipos de celda difieren. En las demás escalas, el códec de Rust devuelve `datetime.timedelta`, mientras que el de Python lanza `ProgrammingError` porque NumPy no dispone de una unidad equivalente. La metadata de los miembros de Dynamic no se expone al driver tras la decodificación en Rust, por lo que conviene usar `native_codec="python"` cuando se necesiten tipos de celda de NumPy o la validación de escalas no admitidas.
* En `query_df`, el códec de Python puede convertir a cadena los valores compuestos almacenados en los shared data de JSON. El códec de Rust devuelve objetos decodificados, lo que coincide con los resultados de `query_np` de ambos códecs.
* Una alternativa `LowCardinality` dentro de un contenedor que se materializa por celda, como `Array(Variant(...))`, produce celdas con valores iguales que no comparten la identidad de objeto por slot de diccionario que sí presenta el códec de Python.
* Las columnas `Nullable(Tuple(...))` con uno o más elementos se decodifican correctamente con el códec de Rust. El códec de Python interpreta mal este layout, por lo que el resultado de Rust es el comportamiento de referencia. Ambos códecs admiten `Nullable(Tuple())`.
* `rust_strict` rechaza las opciones de consulta que la ruta de Rust no implementa, como los `query_formats` personalizados por consulta, en lugar de alterar el comportamiento de forma silenciosa.
* Los errores de conversión y validación en las inserciones de Rust pueden lanzar `DataError` allí donde el códec de Python lanza `ValueError`, y el texto del mensaje puede diferir. Algunos ejemplos son valores `Time` y `Time64` inválidos, direcciones IPv6, dimensiones de QBit, longitudes de `FixedString`, cadenas `Float64` e intentos de insertar elementos en una columna `Tuple()`.
* El codificador de Rust rechaza `b""` para `FixedString(N)` y cadenas numéricas como `"2"` en columnas de enteros. El códec de Python rellena con ceros un valor `FixedString` vacío y convierte las cadenas numéricas.
* El códec de Rust decodifica algunos valores de variantes compartidas de `Dynamic` a sus tipos de Python cuando el códec de Python deja el valor como bytes sin procesar. Por ejemplo, un `Decimal` almacenado puede devolverse como `decimal.Decimal` desde Rust y como un valor binario desde Python.
* En el caso de los valores `Date` en el almacenamiento compartido de `Dynamic`, `query_np` y `query_df` devuelven celdas `datetime.date` con el códec de Rust y celdas `numpy.datetime64` con el códec de Python. Ambos códecs devuelven `datetime.date` desde `query`.
