> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-parallel-read-in-order-multi-part.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Consultas avançadas com ClickHouse Connect

# Consultas avançadas

<h2 id="querycontexts">
  QueryContexts
</h2>

O ClickHouse Connect executa consultas padrão em um `QueryContext`. O `QueryContext` contém as principais estruturas usadas para montar consultas no banco de dados ClickHouse, bem como a configuração usada para processar o resultado em um `QueryResult` ou outra estrutura de dados de resposta. Isso inclui a própria consulta, parâmetros, configurações, formatos de leitura e outras propriedades.

Um `QueryContext` pode ser obtido usando o método `create_query_context` do cliente. Esse método aceita os mesmos parâmetros que o método principal de consulta. Esse contexto de consulta pode então ser passado aos métodos `query`, `query_df` ou `query_np` como o argumento nomeado `context`, em vez de alguns ou de todos os outros argumentos desses métodos. Observe que argumentos adicionais especificados na chamada do método substituirão quaisquer propriedades do `QueryContext`.

O caso de uso mais claro para um `QueryContext` é enviar a mesma consulta com valores diferentes para os parâmetros de associação. Todos os valores dos parâmetros podem ser atualizados chamando o método `QueryContext.set_parameters` com um dicionário, ou qualquer valor individual pode ser atualizado chamando `QueryContext.set_parameter` com o par `key`, `value` desejado.

```python theme={null}
qc = client.create_query_context(
    query="SELECT {k:Int32}",
    parameters={"k": 13},
)
result = client.query(context=qc)
assert result.first_row == (13,)

qc.set_parameter("k", 79)
result = client.query(context=qc)
assert result.first_row == (79,)
```

Observe que `QueryContext`s não são thread-safe, mas é possível obter uma cópia em um ambiente multithread chamando o método `QueryContext.updated_copy`.

<h2 id="streaming-queries">
  Consultas em streaming
</h2>

O cliente ClickHouse Connect oferece vários métodos para recuperar dados como um stream (implementado como um gerador Python):

* `query_column_block_stream` -- Retorna os dados da consulta em blocos, como uma sequência de colunas, usando objetos nativos do Python
* `query_row_block_stream` -- Retorna os dados da consulta como um bloco de linhas, usando objetos nativos do Python
* `query_rows_stream` -- Retorna os dados da consulta como uma sequência de linhas, usando objetos nativos do Python
* `query_np_stream` -- Retorna cada bloco de dados da consulta do ClickHouse como um array NumPy
* `query_df_stream` -- Retorna cada bloco de dados da consulta do ClickHouse como um DataFrame do Pandas
* `query_arrow_stream` -- Retorna os dados da consulta como objetos `RecordBatch` do PyArrow
* `query_df_arrow_stream` -- Retorna cada lote do Arrow como um DataFrame do Pandas ou do Polars, selecionado por `dataframe_library`

Cada método retorna um `StreamContext` que deve ser aberto com uma instrução `with`. Os métodos de streaming do cliente async usam `await` e são abertos com `async with`.

<h3 id="data-blocks">
  Blocos de dados
</h3>

O ClickHouse Connect processa todos os dados do método principal `query` como um stream de blocos recebidos do servidor ClickHouse. Esses blocos são transmitidos de e para o ClickHouse no formato personalizado "Native". Um "bloco" é simplesmente uma sequência de colunas de dados binários, em que cada coluna contém o mesmo número de valores do tipo de dados especificado. (Como banco de dados colunar, o ClickHouse armazena esses dados de forma semelhante.) O tamanho de um bloco retornado por uma consulta é determinado por duas configurações do usuário que podem ser definidas em vários níveis (perfil de usuário, usuário, sessão ou consulta). São elas:

* [max\_block\_size](/pt-BR/reference/settings/session-settings#max_block_size) -- Tamanho máximo do bloco em linhas.
* [preferred\_block\_size\_bytes](/pt-BR/reference/settings/session-settings#preferred_block_size_bytes) -- Tamanho preferencial do bloco em bytes.

Independentemente de `preferred_block_size_bytes`, nenhum bloco terá mais de `max_block_size` linhas. O tamanho real pode ser menor e não deve ser considerado estável.

Ao usar um dos métodos `query_*_stream` do Client, os resultados são retornados bloco a bloco. O ClickHouse Connect carrega apenas um bloco por vez. Isso permite processar grandes volumes de dados sem precisar carregar um conjunto de resultados grande inteiro na memória. Observe que a aplicação deve estar preparada para processar qualquer número de blocos, e o tamanho exato de cada bloco não pode ser controlado.

<h3 id="http-data-buffer-for-slow-processing">
  Buffer de dados HTTP para processamento lento
</h3>

Se uma aplicação consumir blocos muito mais lentamente do que o servidor os produz, a conexão HTTP pode ser encerrada antes que o processamento seja concluído. Aumente a configuração comum `http_buffer_size` se a aplicação tiver memória suficiente para armazenar em buffer mais dados de resposta. O padrão é 10 MiB. Os bytes de resposta em lz4 e zstd permanecem comprimidos nesse buffer, o que aumenta sua capacidade efetiva.

<h3 id="streamcontexts">
  StreamContexts
</h3>

Cada um dos métodos `query_*_stream` (como `query_row_block_stream`) retorna um objeto `StreamContext` do ClickHouse, que combina um contexto e um gerador do Python. Este é o uso básico:

```python theme={null}
with client.query_row_block_stream(
    "SELECT pickup, dropoff, pickup_longitude, pickup_latitude FROM taxi_trips"
) as stream:
    for block in stream:
        for row in block:
            process_trip(row)
```

Observe que tentar usar um `StreamContext` sem uma instrução `with` resultará em erro. Usar um contexto do Python garante que o stream (neste caso, uma resposta HTTP em streaming) seja fechado corretamente, mesmo que nem todos os dados sejam consumidos e/ou uma exceção seja gerada durante o processamento. Além disso, `StreamContext`s só podem ser usados uma vez para consumir o stream. Tentar usar um `StreamContext` depois que ele tiver sido encerrado resultará em `StreamClosedError`.

Se a conexão falhar enquanto um resultado estiver sendo lido, um `StreamFailureError` será gerado em vez de retornar silenciosamente um resultado truncado. Sua mensagem segue a configuração `show_clickhouse_errors` do cliente.

Você pode usar a propriedade `source` do `StreamContext` para acessar o objeto de resultado pai, que inclui nomes de colunas e tipos. Para a maioria dos streams, este é um `QueryResult`; os métodos `query_np_stream` e `query_df_stream` expõem um `NumpyResult`.

<h3 id="stream-types">
  Tipos de streaming
</h3>

O método `query_column_block_stream` retorna o bloco como uma sequência de dados de coluna armazenados como tipos de dados nativos do Python. Usando as consultas `taxi_trips` acima, os dados retornados serão uma lista em que cada elemento é outra lista (ou tupla) contendo todos os dados da coluna correspondente. Assim, `block[0]` seria uma tupla contendo apenas strings. Formatos orientados a colunas são mais usados para executar operações de agregação sobre todos os valores de uma coluna, como somar o total das tarifas.

O método `query_row_block_stream` retorna o bloco como uma sequência de linhas, como em um banco de dados relacional tradicional. Para viagens de táxi, os dados retornados serão uma lista em que cada elemento é outra lista representando uma linha de dados. Assim, `block[0]` conteria todos os campos da primeira viagem de táxi em ordem, `block[1]` conteria uma linha com todos os campos da segunda viagem de táxi, e assim por diante. Resultados orientados a linhas normalmente são usados para exibição ou para processos de transformação.

O método `query_rows_stream` avança automaticamente para o próximo bloco e produz uma linha por vez. Ele é a contraparte linha a linha de `query_row_block_stream`.

O método `query_np_stream` retorna cada bloco como um array NumPy. Quando todas as colunas do resultado compartilham o mesmo dtype do NumPy, o array é bidimensional, com shape `(linhas, colunas)`. Resultados mistos são retornados como um array estruturado unidimensional ou usam o dtype `object`.

O método `query_df_stream` retorna cada bloco do ClickHouse como um DataFrame bidimensional do Pandas. Aqui está um exemplo que mostra que o objeto `StreamContext` pode ser usado como contexto de forma diferida (mas apenas uma vez).

```python theme={null}
df_stream = client.query_df_stream("SELECT * FROM hits")
column_names = df_stream.source.column_names
with df_stream:
    for df in df_stream:
        process_dataframe(df)
```

O método `query_df_arrow_stream` converte batches do Arrow em DataFrames do Pandas ou do Polars. Selecione a biblioteca com `dataframe_library`, cujo valor padrão é `"pandas"`.

Por fim, `query_arrow_stream` encapsula uma resposta `ArrowStream` do ClickHouse em um `StreamContext`. Cada iteração retorna um `RecordBatch` do PyArrow.

<h3 id="streaming-examples">
  Exemplos de streaming
</h3>

<h4 id="stream-rows">
  Fazer streaming de linhas
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Stream large result sets row by row
with client.query_rows_stream("SELECT number, number * 2 as doubled FROM system.numbers LIMIT 100000") as stream:
    for row in stream:
        print(row)  # Process each row
        # Output:
        # (0, 0)
        # (1, 2)
        # (2, 4)
        # Additional rows follow
```

<h4 id="stream-row-blocks">
  Fazer streaming de blocos de linhas
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Stream in blocks of rows (more efficient than row-by-row)
with client.query_row_block_stream("SELECT number, number * 2 FROM system.numbers LIMIT 100000") as stream:
    for block in stream:
        print(f"Received block with {len(block)} rows")
```

<h4 id="stream-pandas-dataframes">
  Fazer streaming de DataFrames do Pandas
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Stream query results as Pandas DataFrames
with client.query_df_stream("SELECT number, toString(number) AS str FROM system.numbers LIMIT 100000") as stream:
    for df in stream:
        # Process each DataFrame block
        print(f"Received DataFrame with {len(df)} rows")
        print(df.head(3))
```

<h4 id="stream-arrow-batches">
  Streaming de lotes de Arrow
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Stream query results as Arrow record batches
with client.query_arrow_stream("SELECT * FROM large_table") as stream:
    for arrow_batch in stream:
        # Process each Arrow batch
        print(f"Received Arrow batch with {arrow_batch.num_rows} rows")
```

<h4 id="async-stream-rows">
  Linhas do streaming assíncrono
</h4>

```python theme={null}
import asyncio

import clickhouse_connect


async def main():
    async_client = await clickhouse_connect.get_async_client()
    async with await async_client.query_rows_stream(
        "SELECT number FROM numbers(100000)"
    ) as stream:
        async for row in stream:
            print(row)


asyncio.run(main())
```

<h2 id="numpy-pandas-and-arrow-queries">
  Consultas com NumPy, Pandas e Arrow
</h2>

O ClickHouse Connect oferece métodos de consulta especializados para trabalhar com estruturas de dados do NumPy, Pandas e Arrow. Esses métodos permitem recuperar os resultados das consultas diretamente nesses formatos de dados populares, sem necessidade de conversão manual.

<h3 id="numpy-queries">
  Consultas com NumPy
</h3>

O método `query_np` retorna os resultados da consulta como um array do NumPy em vez de um `QueryResult` do ClickHouse Connect.

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Query returns a NumPy array
np_array = client.query_np("SELECT number, number * 2 AS doubled FROM system.numbers LIMIT 5")

print(type(np_array))
# Output:
# <class 'numpy.ndarray'>

print(np_array)
# Output:
# [[0 0]
#  [1 2]
#  [2 4]
#  [3 6]
#  [4 8]]
```

<h3 id="pandas-queries">
  Consultas com Pandas
</h3>

O método `query_df` retorna os resultados da consulta como um DataFrame do Pandas, em vez de um `QueryResult` do ClickHouse Connect.

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Query returns a Pandas DataFrame
df = client.query_df("SELECT number, number * 2 AS doubled FROM system.numbers LIMIT 5")

print(type(df))
# Output: <class 'pandas.core.frame.DataFrame'>
print(df)
# Output:
#    number  doubled
# 0       0        0
# 1       1        2
# 2       2        4
# 3       3        6
# 4       4        8
```

<h3 id="pyarrow-queries">
  Consultas com PyArrow
</h3>

O método `query_arrow` retorna uma tabela PyArrow usando diretamente o formato de saída `Arrow` do ClickHouse. Ele aceita `query`, `parameters`, `settings`, `external_data` e `transport_settings`. A opção `use_strings` controla se as colunas `String` do ClickHouse são emitidas como strings do Arrow ou valores binários.

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Query returns a PyArrow Table
arrow_table = client.query_arrow("SELECT number, toString(number) AS str FROM system.numbers LIMIT 3")

print(type(arrow_table))
# Output:
# <class 'pyarrow.lib.Table'>

print(arrow_table)
# Output:
# pyarrow.Table
# number: uint64 not null
# str: string not null
# ----
# number: [[0,1,2]]
# str: [["0","1","2"]]
```

<h3 id="arrow-backed-dataframes">
  DataFrames com Arrow como backend
</h3>

O ClickHouse Connect oferece suporte à criação eficiente de DataFrames a partir de resultados Arrow por meio de `query_df_arrow` e `query_df_arrow_stream`. Esses métodos evitam a conversão por meio de objetos de linha do Python e reutilizam buffers Arrow quando a biblioteca de destino permite:

* `query_df_arrow`: Executa a consulta usando o formato de saída `Arrow` do ClickHouse e retorna um DataFrame.
  * `dataframe_library="pandas"` retorna um DataFrame do Pandas 2.0 ou posterior usando `pd.ArrowDtype`.
  * `dataframe_library="polars"` retorna um DataFrame do Polars criado por meio de `pl.from_arrow`.
* `query_df_arrow_stream`: Transmite lotes Arrow como DataFrames do Pandas ou do Polars.

<h4 id="query-to-arrow-backed-dataframe">
  Consulta para DataFrame com Arrow como backend
</h4>

```python theme={null}
import clickhouse_connect

client = clickhouse_connect.get_client()

# Query returns a Pandas DataFrame with Arrow dtypes (requires pandas 2.x)
df = client.query_df_arrow(
    "SELECT number, toString(number) AS str FROM system.numbers LIMIT 3",
    dataframe_library="pandas"
)

print(df.dtypes)
# Output:
# number    uint64[pyarrow]
# str       string[pyarrow]
# dtype: object

# Or use Polars
polars_df = client.query_df_arrow(
    "SELECT number, toString(number) AS str FROM system.numbers LIMIT 3",
    dataframe_library="polars"
)
print(polars_df.dtypes)
# Output:
# [UInt64, String]

# Streaming into batches of DataFrames (polars shown)
with client.query_df_arrow_stream(
    "SELECT number, toString(number) AS str FROM system.numbers LIMIT 100000", dataframe_library="polars"
) as stream:
    for df_batch in stream:
        print(f"Received {type(df_batch)} batch with {len(df_batch)} rows and dtypes: {df_batch.dtypes}")
```

<h4 id="notes-and-caveats">
  Observações e ressalvas
</h4>

* O ClickHouse controla o esquema do Arrow. Tipos sem uma representação direta em Arrow podem ser retornados usando um tipo físico compatível, incluindo campos binários. Inspecione `table.schema` ou os dtypes do DataFrame antes de aplicar conversões específicas da aplicação.
* Resultados do Pandas com Arrow como backend exigem o Pandas 2.0 ou posterior.
* `use_strings` controla se colunas `String` do ClickHouse usam campos de string do Arrow ou campos binários quando o servidor oferece suporte a `output_format_arrow_string_as_string`.
* `tz_mode="schema"` ainda não é compatível com métodos de consulta baseados em Arrow. Eles emitem um aviso e preservam os metadados de fuso horário fornecidos pela resposta do Arrow.

<h2 id="read-formats">
  Formatos de leitura
</h2>

Os formatos de leitura controlam os valores retornados por `query`, `query_np` e `query_df`. Eles não se aplicam aos métodos raw nem aos métodos Arrow, porque esses métodos usam diretamente um formato de saída do servidor. Por exemplo, definir o formato de leitura de UUID como `"string"` retorna strings UUID em vez de objetos `uuid.UUID`.

O argumento "tipo de dado" de qualquer função de formatação pode incluir curingas. O formato é uma única string em letras minúsculas. Wrappers de contêiner, como `Array`, `Nullable` e `LowCardinality`, preservam o formato selecionado para seu tipo de elemento.

Os formatos de leitura podem ser definidos em vários níveis:

* Globalmente, usando os métodos definidos no pacote `clickhouse_connect.datatypes.format`. Isso controlará o formato do tipo de dado configurado para todas as consultas.

```python theme={null}
from clickhouse_connect.datatypes.format import set_read_format

# Return both IPv6 and IPv4 values as strings
set_read_format("IPv*", "string")

# Return all Date types as the underlying epoch second or epoch day
set_read_format("Date*", "int")
```

* Para toda a consulta, usando o argumento de dicionário opcional `query_formats`. Nesse caso, qualquer coluna (ou subcoluna) dos tipos de dados especificados usará o formato configurado.

```python theme={null}
# Return any UUID column as a string
client.query(
    "SELECT user_id, user_uuid, device_uuid FROM users",
    query_formats={"UUID": "string"},
)
```

* Para uma coluna de resultado específica, use o dicionário opcional `column_formats`. Cada chave é o nome de uma coluna retornada. Seu valor é uma string de formato ou um mapeamento aninhado de nomes de tipos do ClickHouse para formatos, o que é útil para Tuples, Maps e outros tipos de contêiner.

```python theme={null}
# Return IPv6 values in the `dev_address` column as strings
client.query(
    "SELECT device_id, dev_address, gw_address FROM devices",
    column_formats={"dev_address": "string"},
)
```

<h3 id="read-format-options-python-types">
  Opções de formatos de leitura (tipos Python)
</h3>

| Tipo do ClickHouse | Tipo Python nativo | Formatos de leitura | Comentários |
| - | - | - | - |
| Int\[8-64], UInt\[8-32] | int | string | |
| UInt64 | int | signed | No momento, o Superset não lida com valores UInt64 grandes sem sinal |
| \[U]Int\[128,256] | int | string | Os valores int do Pandas e do NumPy têm no máximo 64 bits, então podem ser retornados como strings |
| BFloat16 | float | - | Todos os floats em Python têm 64 bits internamente |
| Float32 | float | string | Todos os floats em Python têm 64 bits internamente |
| Float64 | float | string | |
| Decimal | decimal.Decimal | - | |
| Interval\* | int | string | Os valores são contagens de 64 bits com sinal na unidade do tipo de interval. |
| String | str | bytes | As colunas String do ClickHouse não têm codificação inerente, então também são usadas para dados binários de comprimento variável |
| FixedString | bytes | string | FixedStrings são arrays de bytes de tamanho fixo, mas às vezes são tratados como strings em Python |
| Enum\[8,16] | str | int | O formato nativo retorna rótulos; `int` retorna o inteiro subjacente. |
| Date | datetime.date | int | O formato inteiro retorna dias desde 1970-01-01. |
| Date32 | datetime.date | int | O formato inteiro retorna o deslocamento de dias com sinal mais amplo. |
| DateTime | datetime.datetime | int | O formato inteiro retorna segundos desde o epoch. |
| DateTime64 | datetime.datetime | int | O formato inteiro retorna ticks na precisão da coluna. O `datetime` do Python é limitado a microssegundos. |
| Time | datetime.timedelta | int, string, time | O formato inteiro retorna segundos. O formato `time` é limitado a valores que cabem em `datetime.time`. |
| Time64 | datetime.timedelta | int, string, time | As escalas de 0 a 9 são suportadas. O formato inteiro retorna ticks na precisão da coluna. O `timedelta` do Python é limitado a microssegundos. |
| IPv4 | `ipaddress.IPv4Address` | string, int | Endereços IP podem ser lidos como strings ou inteiros. |
| IPv6 | `ipaddress.IPv6Address` | string | Endereços IP podem ser lidos como strings e, quando formatados corretamente, podem ser inseridos como endereços IP |
| Tuple | dict ou tuple | tuple, dict, json | Tuplas nomeadas retornam dicionários por padrão; tuplas sem nome retornam tuplas. Um valor `Tuple()` retorna `()`. |
| Map | dict | pairs | `dict` é o padrão. `pairs` retorna uma lista de tuplas de chave/valor e preserva chaves duplicadas. |
| Nested | Sequence\[dict] | - | |
| UUID | uuid.UUID | string | UUIDs podem ser lidos como strings formatadas de acordo com a RFC 4122<br /> |
| JSON | dict | string | Um dicionário Python é retornado por padrão. O formato `string` retornará uma string JSON |
| Variant | object | typed | `typed` retorna `TypedVariant(value, type_name)` para preservar o tipo do membro de origem. |
| Dynamic | object | - | Retorna o tipo Python correspondente ao tipo de dado do ClickHouse armazenado para o valor |
| MultiPoint | list\[tuple] | - | Cada ponto é retornado como uma tupla de 2 elementos. |
| Geometry | tuple ou list | typed | Os valores Point são tuplas de 2 elementos. Os demais membros, incluindo MultiPoint, usam listas aninhadas. Selecione `typed` com a chave `Geometry` para preservar o tipo do membro. As configurações de formato de `Variant` não se aplicam. |
| QBit | list\[float] | - | O NumPy é usado automaticamente para uma transposição de bits mais rápida quando instalado. |

`query_np`, `query_np_stream`, `query_df` e `query_df_stream` suportam as escalas 0, 3, 6 e 9 de `Time64`. As demais escalas geram `ProgrammingError`, pois não têm uma unidade de tempo correspondente no NumPy. Use uma consulta Python padrão com o formato de leitura `int` ou `string` para preservar essas precisões. O [codec Rust](/pt-BR/integrations/language-clients/python/rust-codec#known-behavior-differences) experimental documenta uma exceção para `Time64` armazenado dentro de `Dynamic`.

<h3 id="map-pairs">
  Valores Map com chaves duplicadas
</h3>

Os Maps do ClickHouse podem conter chaves duplicadas. Por padrão, o dicionário Python mantém apenas o último valor de cada chave. Selecione o formato de leitura `pairs` para preservar todos os pares na ordem em que são retornados pelo servidor:

```python theme={null}
result = client.query(
    "SELECT map('key', 'X', 'key', 'Y') AS m",
    query_formats={"Map": "pairs"},
)
print(result.first_item["m"])
# [('key', 'X'), ('key', 'Y')]
```

O formato é aplicado recursivamente a Maps aninhados em outros tipos do ClickHouse, incluindo Arrays, Tuples, caminhos tipados de JSON, Dynamic, Variant e outros Maps. Ele também funciona com `query_np`, `query_df` e suas variantes de streaming. Para selecionar Maps em uma única coluna do resultado, use `column_formats={"m": {"Map": "pairs"}}`. Para defini-lo globalmente, use `set_read_format("Map", "pairs")`.

Este é um formato de leitura. Inserts nativos de Map continuam exigindo dicionários e não aceitam listas de pares. Para ler e gravar chaves duplicadas sem perdas, use `query_arrow` e `insert_arrow`. Os formatos de leitura não afetam os métodos Arrow. Assim como em outras substituições de formato de leitura, `native_codec="rust"` recorre ao Python, enquanto `native_codec="rust_strict"` gera `NotSupportedError`.

<h2 id="external-data">
  Dados externos
</h2>

As consultas do ClickHouse podem aceitar dados externos em qualquer formato de entrada compatível. O cliente envia os dados como parte da requisição, e a consulta pode referenciá-los como uma tabela externa temporária. Consulte a [documentação de dados externos do ClickHouse](/pt-BR/reference/engines/table-engines/special/external-data). Os métodos de consulta do cliente aceitam um objeto `clickhouse_connect.driver.external.ExternalData` por meio do parâmetro `external_data`.

| Nome | Tipo | Descrição |
| - | - | - |
| file\_path | str | Caminho para um arquivo no sistema local, de onde os dados externos serão lidos. `file_path` ou `data` é obrigatório |
| file\_name | str | O nome do "arquivo" de dados externos. Se não for fornecido, será obtido da parte do nome do arquivo em `file_path`. O nome da tabela externa é o nome do arquivo sem a extensão |
| data | bytes | Os dados externos em forma binária (em vez de serem lidos de um arquivo). `data` ou `file_path` é obrigatório |
| fmt | str | [Formato de entrada](/pt-BR/reference/formats) dos dados no ClickHouse. O padrão é `TSV` |
| types | str or seq of str | Uma lista de tipos de dados das colunas nos dados externos. Se for uma string, os tipos devem ser separados por vírgulas. `types` ou `structure` é obrigatório |
| structure | str or seq of str | Uma lista de nomes de colunas + tipos de dados nos dados (veja os exemplos). `structure` ou `types` é obrigatório |
| mime\_type | str | Tipo MIME opcional dos dados do arquivo. Atualmente, o ClickHouse ignora esse subcabeçalho HTTP |

Este exemplo faz uma junção entre um arquivo CSV externo e uma tabela `directors` armazenada no servidor:

```python theme={null}
import clickhouse_connect
from clickhouse_connect.driver.external import ExternalData

client = clickhouse_connect.get_client()
ext_data = ExternalData(
    file_path="/data/movies.csv",
    fmt="CSV",
    structure=[
        "movie String",
        "year UInt16",
        "rating Decimal32(3)",
        "director String",
    ],
)
result = client.query(
    "SELECT name, avg(rating) "
    "FROM directors INNER JOIN movies ON directors.name = movies.director "
    "GROUP BY directors.name",
    external_data=ext_data,
).result_rows
```

Arquivos de dados externos adicionais podem ser adicionados ao objeto `ExternalData` inicial usando o método `add_file`, que aceita os mesmos parâmetros do construtor. Em HTTP, todos os dados externos são transmitidos como parte de um upload de arquivo `multi-part/form-data`.

O backend chDB não oferece suporte a dados externos.

<h2 id="time-zones">
  Fusos horários
</h2>

Os valores `DateTime` e `DateTime64` do ClickHouse são transmitidos como valores numéricos baseados em epoch. O ClickHouse Connect os converte em objetos `datetime` do Python usando metadados de coluna, substituições de consulta e a política de fuso horário do cliente.

O cliente tem duas opções independentes de fuso horário:

* `tz_source` seleciona o fuso horário de fallback para colunas sem metadados explícitos de fuso horário:
  * `"auto"` é o padrão. Usa o fuso horário do servidor quando o cliente consegue resolvê-lo com segurança em transições de horário de verão; caso contrário, usa o fuso horário local.
  * `"server"` sempre usa o fuso horário do servidor.
  * `"local"` sempre usa o fuso horário do processo local.
* `tz_mode` controla o tratamento de fuso horário:
  * `"naive_utc"` é o padrão. Resultados em UTC e equivalentes a UTC são retornados como objetos `datetime` sem fuso horário, para compatibilidade retroativa.
  * `"aware"` preserva o `tzinfo` de UTC e retorna valores UTC com fuso horário.
  * `"schema"` retorna valores com fuso horário somente quando o tipo da coluna declara um fuso horário, e valores sem fuso horário para colunas `DateTime`/`DateTime64` sem fuso horário.

Para consultas normais com `"naive_utc"` e `"aware"`, o fuso horário ativo é selecionado nesta ordem:

1. Uma substituição `column_tzs` por coluna.
2. Metadados de fuso horário no tipo de coluna do ClickHouse.
3. A substituição `query_tz` para toda a consulta.
4. Informações de fuso horário retornadas com a resposta HTTP.
5. O fallback selecionado por `tz_source`.

`tz_mode="schema"` ignora os fusos horários da consulta e de fallback, mas uma substituição `column_tzs` explícita ainda tem precedência.

```python theme={null}
result = client.query(
    "SELECT "
    "toDateTime('2026-01-15 12:00:00', 'UTC') AS utc_time, "
    "toDateTime('2026-01-15 12:00:00', 'America/Denver') AS denver_time",
    tz_mode="aware",
)

assert result.first_row[0].tzinfo is not None
assert result.first_row[1].tzinfo is not None
```

Os nomes de fusos horários são resolvidos pelo módulo `zoneinfo` da biblioteca padrão. Instalações no Windows recebem `tzdata` automaticamente. Em imagens Linux mínimas sem um banco de dados de fusos horários da IANA, instale `clickhouse-connect[tzdata]`.

Os resultados do Pandas preservam a resolução natural de cada tipo do ClickHouse, como `datetime64[s]` para `DateTime` e `datetime64[ms]` para `DateTime64(3)`. Os métodos de DataFrame com Arrow como backend `query_df_arrow` e `query_df_arrow_stream` ainda não implementam `tz_mode="schema"` e emitirão um aviso quando isso for solicitado. `query_arrow` e `query_arrow_stream` retornam os metadados de fuso horário da resposta Arrow inalterados.
