> ## 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.

> Codec Rust compilado opcional para o ClickHouse Connect

# Codec nativo em Rust

O ClickHouse Connect pode decodificar resultados de consultas e codificar inserções com um codec Rust compilado em vez da implementação padrão em Python e Cython. O codec Rust se aplica apenas ao tráfego `FORMAT Native` gerenciado pelo cliente, que abrange `query`, `query_np`, `query_df`, suas variantes de streaming por block e por linha, e as inserções, incluindo `insert_df`. Os métodos Arrow usam `FORMAT Arrow` e não são afetados, assim como as consultas raw, as inserções raw e os formatos não Native.

O codec é experimental e de uso opcional. O codec Python continua sendo o padrão.

## Instalação

O codec compilado é distribuído como um wheel separado, chamado `clickhouse-connect-core`, que fornece o módulo de extensão `_ch_core`. Instale o codec junto com as integrações usadas pela sua aplicação:

```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
```

Os wheels do núcleo são publicados para CPython 3.10 a 3.14 e para o CPython 3.14t com free-threading no Linux, macOS e Windows. No Python com free-threading, importar a extensão do núcleo não reabilita o GIL.

A saída comum de NumPy e Pandas em Rust não exige PyArrow nem qualquer outro pacote Arrow. Isso inclui `query_np`, `query_df`, suas variantes de streaming e `query(..., use_numpy=True)`. Consultas NumPy não exigem Pandas. Adicione o extra `async` para usar o cliente assíncrono.

O PyArrow continua sendo necessário para os métodos Arrow e para o armazenamento Pandas com Arrow como backend. Instale o extra `arrow` para usar esses recursos:

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

A saída estendida de strings do Pandas segue a opção `mode.string_storage` do Pandas. Quando o PyArrow está instalado, as strings usam a conversão Arrow existente, com validação UTF-8 completa, em qualquer um dos backends de armazenamento. Sem o PyArrow, o driver usa a conversão de objetos em Rust, e o armazenamento padrão do Pandas usa strings Python. Solicitar explicitamente o armazenamento de strings Arrow sem o PyArrow gera um erro de dependência. UTF-8 inválido mantém a renderização hexadecimal existente em qualquer um dos backends de armazenamento.

O codec, seu empacotamento e seu conjunto de dependências são experimentais. A conversão direta de buffers agora trata colunas de inteiros não anuláveis de 8 a 64 bits, Float32/64, Boolean, BFloat16, Interval, Date, Date32, DateTime e DateTime64. Colunas escalares Time e Time64, incluindo valores anuláveis, também usam buffers diretos, assim como BFloat16 anulável e a saída estendida do Pandas para inteiros, floats e Interval anuláveis. BFloat16 mantém a saída float32 e sua política atual de valores ausentes Float32 do Pandas. Valores Interval continuam sendo contagens com sinal em sua unidade declarada. A conversão temporal mantém as unidades declaradas e as regras de fuso horário existentes. Aliases SimpleAggregateFunction anuláveis de Time64 agora retornam durações corretas e NaT para valores NULL. Colunas escalares anuláveis DateTime64(9) também usam buffers para preservar nanossegundos na saída do NumPy e do Pandas. As demais datas e timestamps anuláveis mantêm seus caminhos de conversão de objetos.

Arrays de Time/Time64, incluindo arrays aninhados e folhas anuláveis, e LowCardinality(Time), incluindo valores anuláveis, também usam buffers diretos. O aninhamento, as unidades de duração e as representações de nulos permanecem inalterados. LowCardinality(Time64) continua sem suporte no núcleo em Rust.

Para DateTime64(9) escalar anulável, `query_df` e `query_df_stream` preservam todos os nove dígitos fracionários, inclusive por meio de aliases SimpleAggregateFunction. No Pandas 3, colunas datetime na saída padrão agora usam unidades de nanossegundos em vez de microssegundos. A inferência atual de dtype object para blocos totalmente NULL permanece inalterada. Se um fuso horário nomeado colocar um valor fora do intervalo de nanossegundos do Pandas, essa coluna mantém a conversão de objetos e o comportamento de intervalo anteriores.

Para essas colunas, os campos de objeto de `query_np` e `query_np_stream` agora contêm células `numpy.datetime64` em vez de células `datetime` do Python, com `None` para NULL do SQL. Valores com fuso nomeado usam ticks UTC sem metadados de fuso horário, assim como o codec Python. Isso preserva os nanossegundos sem exigir o Pandas. Use `query_df` se precisar de timestamps com fuso horário. Os demais tipos de células temporais anuláveis do NumPy permanecem inalterados.

Consultas NumPy e Pandas de DateTime64 escalar rejeitam precisões diferentes de 0, 3, 6 e 9 com `ProgrammingError`, inclusive em colunas anuláveis e aliases SimpleAggregateFunction.

Se um codec Rust for selecionado e o módulo compilado não estiver instalado, a criação do cliente gera um `NotSupportedError` que informa este comando de instalação.

## Habilitando o codec

Selecione o codec com a opção de cliente `native_codec`:

```python theme={null}
import clickhouse_connect

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

Valores aceitos:

| Value | Behavior |
| - | - |
| `python` | Padrão. O codec existente em Python e Cython. |
| `rust` | Dá preferência ao codec Rust. Consultas com opções sem suporte e inserções com tipos não suportados são roteados para o codec Python. |
| `rust_strict` | Exige o codec Rust. Opções e tipos sem suporte geram erro em vez de serem roteados. |

O padrão também pode ser definido pela configuração comum `native_codec` ou pela variável de ambiente `CLICKHOUSE_CONNECT_NATIVE_CODEC`. A precedência é: primeiro o keyword argument do cliente, depois a configuração comum e, por fim, a variável de ambiente.

A opção é ignorada para clientes com `interface="chdb"`, que sempre usam o codec Python.

## Quando usar o codec Rust

O codec Rust é mais útil para resultados grandes de DataFrame com tipos de texto, contêineres e tipos complexos como `String`, `LowCardinality`, `Map`, `Array`, `JSON`, `Decimal` e `UUID`. Ele também pode ajudar em streams de blocos grandes de linhas e colunas, cargas de trabalho com consultas concorrentes e inserts em massa.

Resultados pequenos e consultas limitadas pela rede podem apresentar pouca diferença. Resultados numéricos simples já utilizam caminhos em massa eficientes no codec Python, portanto também tendem a se beneficiar menos.

Buffers diretos evitam arrays intermediários do Arrow para os tipos compatíveis. A montagem final dos resultados em NumPy e Pandas ainda pode alocar e copiar dados, portanto isso não torna todo resultado de consulta zero-copy.

Sem o PyArrow, a conversão de strings no Rust cria objetos string do Python a partir de cada bloco decodificado. Com os tamanhos de bloco padrão, o pico de memória para resultados grandes de String é próximo ao do codec Python. Blocos muito grandes, como um único bloco com um milhão de linhas, mantêm todo o bloco decodificado em memória enquanto suas strings são criadas e podem consumir mais memória de pico do que o codec Python. Para resultados grandes com Pandas `StringDtype`, instale o extra `arrow` e use o armazenamento de strings do Arrow. O Pandas 3 seleciona o armazenamento Arrow por padrão quando o PyArrow está instalado. O Pandas 2 requer `pd.options.mode.string_storage = "pyarrow"`.

Chamadas `query()` com buffer sobre resultados muito largos ou totalmente numéricos podem, atualmente, ser mais lentas e consumir mais memória de pico com o codec Rust. Para essas cargas de trabalho, prefira `query_df`, `query_row_block_stream` ou `query_column_block_stream`. Para NumPy e Pandas, `query_np_stream` e `query_df_stream` também podem reduzir o pico de memória. Processe e libere cada bloco em vez de acumular todo o stream. O uso de memória ainda depende do tamanho de cada bloco, portanto fazer streaming de um único bloco grande não traz o mesmo benefício.

Faça um benchmark da sua própria carga de trabalho antes de adotar o codec. Use `native_codec="rust_strict"` durante as medições para que uma opção sem suporte ou uma dependência ausente gere um erro, em vez de encaminhar silenciosamente a consulta para o Python.

## Regras de fallback

As decisões de fallback são tomadas antes que qualquer byte seja lido ou enviado, portanto nunca ocorre troca de codec no meio do stream. Para queries, a escolha acontece antes de o response body ser consumido. Para inserções, o codificador Rust só é selecionado quando todos os tipos de coluna têm suporte; caso contrário, a inserção inteira é executada no codec Python.

Quando `naive_datetime_insert="server"` está ativo, o `rust` encaminha ao codec Python qualquer inserção que contenha uma coluna `DateTime` ou `DateTime64`, de modo que a timezone declarada da coluna ou a server timezone seja aplicada. Já o `rust_strict` rejeita essa combinação. O modo padrão `naive_datetime_insert="local"` continua usando o codificador Rust.

Queries de metadados internas do driver, incluindo as instruções de reflexão do dialect do SQLAlchemy, sempre usam o codec Python, de forma silenciosa, em todos os modos.

Payloads Native malformados detectados pelo codec Rust geram `DataError`.

## Versioning

O `clickhouse-connect-core` é versionado de forma independente do `clickhouse-connect`. O extra `rust` requer `clickhouse-connect-core>=0.2.1,<0.3`. Quando um codec Rust é selecionado, o driver verifica tanto a versão da API de binding quanto a capability de buffer de coluna. A wheel do core 0.2.0 publicada não tem a capability de buffer de coluna. Se a wheel instalada for incompatível, a criação do cliente gera um `NotSupportedError` tanto para `rust` quanto para `rust_strict`, com este comando de upgrade:

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

Correções e melhorias de desempenho no codec compilado são publicadas como lançamentos do `clickhouse-connect-core` e podem ser obtidas com um upgrade para uma wheel do core compatível. Alterações na integração Rust do driver exigem um upgrade do `clickhouse-connect`.

## Diferenças de comportamento conhecidas

O codec Rust busca paridade célula a célula com o codec Python. As seguintes diferenças são conhecidas.

* Os resultados de `query_np` e `query_df` para colunas `Variant` contêm objetos Python simples em vez de valores escalares do numpy. Os valores são iguais, mas os tipos das células diferem.
* Valores `Dynamic` que contêm `Time64` são materializados como `datetime.timedelta` nos resultados de `query_np` e `query_df` do Rust. Nas escalas 0, 3, 6 e 9, os valores são iguais às células `numpy.timedelta64` do codec Python, mas os tipos das células diferem. Nas demais escalas, o codec Rust retorna `datetime.timedelta`, enquanto o codec Python gera `ProgrammingError`, pois o NumPy não possui uma unidade correspondente. Os metadados dos membros de `Dynamic` não são expostos ao driver após a decodificação em Rust; portanto, use `native_codec="python"` quando forem necessários os tipos de célula do NumPy ou a validação de escalas sem suporte.
* Em `query_df`, o codec Python pode converter em string valores compostos armazenados em shared data de JSON. O codec Rust retorna objetos decodificados, o que corresponde aos resultados de `query_np` de ambos os codecs.
* Uma alternativa `LowCardinality` dentro de um contêiner que se materializa por célula, como `Array(Variant(...))`, produz células com valores iguais que não compartilham a identidade de objeto por slot de dicionário apresentada pelo codec Python.
* Colunas `Nullable(Tuple(...))` com um ou mais elementos são decodificadas corretamente no codec Rust. O codec Python interpreta esse layout de forma incorreta, e o resultado do Rust é o comportamento de referência. Ambos os codecs suportam `Nullable(Tuple())`.
* `rust_strict` rejeita opções de consulta que o caminho Rust não implementa, como `query_formats` customizados por consulta, em vez de alterar o comportamento silenciosamente.
* Erros de conversão e de validação de insert no Rust podem gerar `DataError` onde o codec Python gera `ValueError`, e o texto da mensagem pode diferir. Entre os exemplos estão valores `Time` e `Time64` inválidos, endereços IPv6, dimensões de QBit, comprimentos de `FixedString`, strings `Float64` e tentativas de inserir elementos em uma coluna `Tuple()`.
* O codificador Rust rejeita `b""` para `FixedString(N)` e strings numéricas como `"2"` em colunas de inteiros. O codec Python preenche com zeros um valor `FixedString` vazio e converte strings numéricas.
* O codec Rust decodifica alguns valores de variante compartilhada de `Dynamic` para seus tipos Python nos casos em que o codec Python mantém o valor como raw bytes. Por exemplo, um `Decimal` armazenado pode ser retornado como `decimal.Decimal` no Rust e como um valor binário no Python.
* Para valores `Date` no armazenamento compartilhado de `Dynamic`, `query_np` e `query_df` retornam células `datetime.date` com o codec Rust e células `numpy.datetime64` com o codec Python. Ambos os codecs retornam `datetime.date` a partir de `query`.
