Visão geral
- Usa
serdepara codificar/decodificar linhas. - Suporta atributos do
serde:skip_serializing,skip_deserializing,rename. - Usa o formato
RowBinaryno transporte HTTP.- Há planos para migrar para
Nativesobre TCP.
- Há planos para migrar para
- Suporta TLS (por meio das features
native-tlserustls-tls). - Suporta compressão e descompressão (LZ4).
- Fornece APIs para selecionar ou inserir dados, executar DDLs e fazer batching no cliente.
- Fornece mocks úteis para testes unitários.
Instalação
Cargo.toml:
Recursos do Cargo
lz4(ativado por padrão) — habilita as variantesCompression::Lz4eCompression::Lz4Hc(_). Quando ativado,Compression::Lz4é usado por padrão em todas as queries, exceto paraWATCH.native-tls— oferece suporte a URLs com o schemaHTTPSviahyper-tls, que faz link com o OpenSSL.rustls-tls— oferece suporte a URLs com o schemaHTTPSviahyper-rustls, que não faz link com o OpenSSL.inserter— habilitaclient.inserter().test-util— adiciona mocks. Veja o exemplo. Use-o apenas emdev-dependencies.watch— habilita a funcionalidadeclient.watch. Consulte a seção correspondente para mais detalhes.uuid— adicionaserde::uuidpara funcionar com a crate uuid.time— adicionaserde::timepara funcionar com a crate time.
Compatibilidade entre versões do ClickHouse
wa-37420 para resolver esse problema. Observação: esse recurso não deve ser usado com versões mais recentes do ClickHouse.
Exemplos
Uso
O crate ch2rs é útil para gerar um tipo de linha com base no ClickHouse.
Criando uma instância de cliente
Conexão HTTPS ou ClickHouse Cloud
rustls-tls ou native-tls.
Em seguida, crie o cliente normalmente. Neste exemplo, as variáveis de ambiente são usadas para armazenar os detalhes da conexão:
- Exemplo de HTTPS com ClickHouse Cloud no repositório do cliente. Isso também deve ser aplicável a conexões HTTPS em ambientes on-premise.
Selecionando linhas
- O marcador
?fieldsé substituído porno, name(campos deRow). - O marcador
?é substituído pelos valores nas chamadasbind()a seguir. - Os métodos práticos
fetch_one::<Row>()efetch_all::<Row>()podem ser usados para obter a primeira linha ou todas as linhas, respectivamente. sql::Identifierpode ser usado para associar nomes de tabelas.
query(...).with_option("wait_end_of_query", "1") para ativar a bufferização da resposta no servidor. Mais detalhes. A opção buffer_size também pode ser útil.
Inserção de linhas
- Se
end()não for chamado, oINSERTserá abortado. - As linhas são enviadas progressivamente como um stream para distribuir a carga de rede.
- O ClickHouse insere lotes de forma atômica somente se todas as linhas couberem na mesma partição e se a quantidade delas for menor que
max_insert_block_size.
Async insert (batching no servidor)
async_insert ao método insert (ou até mesmo à própria instância Client, para que isso afete todas as chamadas de insert).
- Exemplo de async insert no repositório do cliente.
Recurso Inserter (batching no cliente)
inserter do Cargo.
Inserterencerra a inserção ativa emcommit()se qualquer um dos limites (max_bytes,max_rows,period) for atingido.- O intervalo entre o encerramento de
INSERTs ativos pode ser ajustado comwith_period_biaspara evitar picos de carga causados por insertores paralelos. Inserter::time_left()pode ser usado para detectar quando o período atual termina. ChameInserter::commit()novamente para verificar os limites se o seu stream emitir itens com pouca frequência.- Os limiares de tempo são implementados com o crate quanta para acelerar o
inserter. Ele não é usado setest-utilestiver habilitado (assim, o tempo pode ser controlado portokio::time::advance()em testes personalizados). - Todas as linhas entre chamadas de
commit()são inseridas na mesma instruçãoINSERT.
Executando DDLs
wait_end_of_query. Isso pode ser feito assim:
Configurações do ClickHouse
with_option. Por exemplo:
query, isso funciona de maneira semelhante nos métodos insert e inserter; além disso, o mesmo método pode ser chamado na instância Client para definir configurações globais para todas as consultas.
ID da consulta
.with_option, você pode definir a opção query_id para identificar consultas no log de consultas do ClickHouse.
query, ele também funciona de forma semelhante com os métodos insert e inserter.
Veja também: exemplo de query_id no repositório do cliente.
ID da sessão
query_id, você pode definir session_id para executar as instruções na mesma sessão. session_id pode ser definido globalmente no nível do cliente ou por chamada de query, insert ou inserter.
Cabeçalhos HTTP personalizados
Cliente HTTP personalizado
Tipos de dados
Veja também estes exemplos adicionais:
(U)Int(8|16|32|64|128)corresponde aos tipos(u|i)(8|16|32|64|128)equivalentes, ou a newtypes baseados neles.(U)Int256não tem suporte direto, mas há uma solução alternativa.Float(32|64)corresponde aos tiposf(32|64)equivalentes, ou a newtypes baseados neles.Decimal(32|64|128)corresponde aos tiposi(32|64|128)equivalentes, ou a newtypes baseados neles. É mais prático usarfixnumou outra implementação de números com sinal em ponto fixo.Booleancorresponde aboolou a newtypes baseados nele.Stringcorresponde a qualquer tipo de string ou bytes, por exemplo,&str,&[u8],String,Vec<u8>ouSmartString. Newtypes também têm suporte. Para armazenar bytes, considere usarserde_bytes, pois é mais eficiente.
FixedString(N)tem suporte como um array de bytes, por exemplo[u8; N].
Enum(8|16)têm suporte por meio deserde_repr.
UUIDé mapeado de e parauuid::Uuidusandoserde::uuid. Requer o recursouuid.
IPv6é convertido de/parastd::net::Ipv6Addr.IPv4é convertido de/parastd::net::Ipv4Addrusandoserde::ipv4.
Dateé mapeado de/parau16ou um newtype baseado nele e representa um número de dias decorridos desde1970-01-01. Além disso,time::Datetambém é compatível com o uso deserde::time::date, o que requer o recursotime.
Date32é mapeado de/parai32ou umnewtypebaseado nele e representa um número de dias decorridos desde1970-01-01. Além disso,time::Datetambém é compatível com o uso deserde::time::date32, o que requer o recursotime.
DateTimeé convertido de/parau32ou um newtype baseado nele e representa um número de segundos decorridos desde a epoch UNIX. Além disso,time::OffsetDateTimeé compatível ao usarserde::time::datetime, o que requer o recursotime.
DateTime64(_)é mapeado de/parai32ou um newtype baseado nele e representa o tempo decorrido desde a epoch UNIX. Além disso,time::OffsetDateTimetambém tem suporte usandoserde::time::datetime64::*, o que exige a featuretime.
Tuple(A, B, ...)é mapeado de/para(A, B, ...)ou umnewtypesobre ele.Array(_)é mapeado de/para qualquer slice, por exemploVec<_>,&[_].newtypestambém são compatíveis.Map(K, V)se comporta comoArray((K, V)).LowCardinality(_)tem suporte transparente.Nullable(_)é mapeado de/paraOption<_>. Para os helpersclickhouse::serde::*, adicione::option.
- Há suporte a
Nestedao fornecer vários arrays com renomeação.
- Há suporte a tipos
Geo.Pointse comporta como uma tupla(f64, f64), e os demais tipos são apenas sequências de pontos.
- Os tipos de dados
Variant,Dynamice o (novo)JSONainda não têm suporte.
Simulação
SELECT, INSERT e WATCH. Esse recurso pode ser habilitado com o recurso test-util. Use-a apenas como dev-dependency.
Veja o exemplo.
Solução de problemas
CANNOT_READ_ALL_DATA
CANNOT_READ_ALL_DATA é que a definição da linha no lado da aplicação não corresponde à do ClickHouse.
Considere a seguinte tabela:
EventLog estiver definido no lado da aplicação com tipos incompatíveis, por exemplo:
EventLog:
Limitações conhecidas
- Os tipos de dados
Variant,DynamiceJSON(novo) ainda não são suportados. - O binding de parâmetros no servidor ainda não é suportado; consulte esta issue para acompanhar.