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

> ClickHouse Connectを使用した高度なクエリ

# 高度なクエリ

<div id="querycontexts">
  ## QueryContexts
</div>

ClickHouse Connect は、標準のクエリを `QueryContext` 内で実行します。`QueryContext` には、ClickHouse データベースに対するクエリの構築に使用される主要な構造と、結果を `QueryResult` またはその他の応答データ構造に変換するための設定が含まれます。これには、クエリ自体、パラメータ、設定、読み取りフォーマット、その他のプロパティが含まれます。

`QueryContext` は、クライアントの `create_query_context` メソッドを使用して取得できます。このメソッドは、中核となるクエリメソッドと同じパラメータを受け取ります。取得したクエリコンテキストは、その後 `query`、`query_df`、または `query_np` メソッドに対して、これらのメソッドの他の引数の一部またはすべての代わりに、`context` キーワード引数として渡すことができます。なお、メソッド呼び出しで追加指定した引数は、QueryContext の各プロパティより優先されます。

`QueryContext` の最もわかりやすいユースケースは、同じクエリを異なるバインドパラメータ値で送信することです。すべてのパラメータ値は、辞書を指定して `QueryContext.set_parameters` メソッドを呼び出すことで更新できます。また、個々の値は、目的の `key`、`value` の組を指定して `QueryContext.set_parameter` を呼び出すことで更新できます。

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

`QueryContext` はスレッドセーフではありませんが、マルチスレッド環境では `QueryContext.updated_copy` メソッドを呼び出すことで、そのコピーを取得できます。

<div id="streaming-queries">
  ## ストリーミングクエリ
</div>

ClickHouse Connect クライアントは、データをストリームとして取得するための複数のメソッドを提供しています (Python ジェネレーターとして実装されています) 。

* `query_column_block_stream` -- クエリデータを、Python ネイティブオブジェクトを使用して、カラムのシーケンスとしてブロック単位で返します
* `query_row_block_stream` -- クエリデータを、Python ネイティブオブジェクトを使用して、行のブロックとして返します
* `query_rows_stream` -- クエリデータを、Python ネイティブオブジェクトを使用して、行のシーケンスとして返します
* `query_np_stream` -- クエリデータの各 ClickHouse ブロックを NumPy 配列として返します
* `query_df_stream` -- クエリデータの各 ClickHouse ブロックを Pandas DataFrame として返します
* `query_arrow_stream` -- クエリデータを PyArrow `RecordBatch` オブジェクトとして返します
* `query_df_arrow_stream` -- `dataframe_library` によって選択された Pandas または Polars DataFrame として、各 Arrow バッチを返します

各メソッドは `StreamContext` を返し、`with` ステートメントで開く必要があります。async クライアントのストリーミングメソッドは `await` で待機し、`async with` で開きます。

<div id="data-blocks">
  ### データブロック
</div>

ClickHouse Connect は、主要な `query` メソッドから取得されるすべてのデータを、ClickHouse server から受信するブロックのストリームとして処理します。これらのブロックは、ClickHouse との間でカスタムの「Native」フォーマットを使って送受信されます。「ブロック」は、指定されたデータ型のバイナリデータで構成されたカラムの並びにすぎず、各カラムには同じ数のデータ値が含まれます。 (列指向データベースである ClickHouse では、データもこれに近い形式で保存されます。) クエリから返されるブロックのサイズは、複数のレベル (user profile、user、session、または query) で設定できる 2 つのユーザー設定によって決まります。設定項目は次のとおりです。

* [max\_block\_size](/ja/reference/settings/session-settings#max_block_size) -- ブロックサイズの上限 (行数) 。
* [preferred\_block\_size\_bytes](/ja/reference/settings/session-settings#preferred_block_size_bytes) -- 推奨されるブロックサイズ (バイト数) 。

`preferred_block_size_bytes` にかかわらず、ブロックが `max_block_size` 行を超えることはありません。実際のサイズはこれより小さい場合があり、安定しているものとして扱うべきではありません。

Client の `query_*_stream` メソッドのいずれかを使用すると、結果はブロック単位で返されます。ClickHouse Connect は、一度に 1 つのブロックだけを読み込みます。これにより、大きな結果セット全体をメモリに読み込むことなく、大量のデータを処理できます。アプリケーションは、任意の数のブロックを処理できるようにしておく必要があり、各ブロックの正確なサイズは制御できない点に注意してください。

<div id="http-data-buffer-for-slow-processing">
  ### 処理が遅い場合の HTTP データバッファ
</div>

アプリケーションによるブロックの消費がサーバーの生成より大幅に遅い場合、処理が完了する前に HTTP 接続が閉じられることがあります。アプリケーションに、より多くの応答データをバッファリングできるだけの十分なメモリがある場合は、共通設定の `http_buffer_size` を増やしてください。デフォルトは 10 MiB です。lz4 と zstd の応答バイトはこのバッファ内で圧縮されたまま保持されるため、実効容量は大きくなります。

<div id="streamcontexts">
  ### StreamContexts
</div>

各 `query_*_stream` メソッド (`query_row_block_stream` など) は、Python のコンテキストマネージャーとジェネレーターを組み合わせた ClickHouse の `StreamContext` オブジェクトを返します。基本的な使い方は次のとおりです。

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

`with` ステートメントを使わずに `StreamContext` を使用しようとすると、エラーが発生する点に注意してください。Python のコンテキストを使うことで、ストリーム (この場合はストリーミング HTTP レスポンス) は、すべてのデータが消費されなかった場合や、処理中に例外が発生した場合でも、適切にクローズされます。また、`StreamContext` はストリームの消費に一度しか使用できません。終了後の `StreamContext` を使用しようとすると、`StreamClosedError` が発生します。

結果の読み取り中に接続が失敗した場合、切り詰められた結果が暗黙的に返されるのではなく、`StreamFailureError` が発生します。そのメッセージはクライアントの `show_clickhouse_errors` 設定に従います。

`StreamContext` の `source` プロパティを使うと、カラム名と型を含む親の結果オブジェクトにアクセスできます。ほとんどのストリームではこれは `QueryResult` ですが、`query_np_stream` と `query_df_stream` メソッドでは代わりに `NumpyResult` が公開されます。

<div id="stream-types">
  ### ストリームの種類
</div>

`query_column_block_stream` メソッドは、ブロックを、ネイティブの Python データ型として格納されたカラムデータのシーケンスとして返します。上記の `taxi_trips` クエリを使うと、返されるデータはリストになり、その各要素は対応するカラムのすべてのデータを含む別のリスト (またはタプル) になります。したがって `block[0]` は、文字列だけを含むタプルになります。カラム指向のフォーマットは、運賃の合計を足し上げるといった、あるカラム内のすべての値に対する集計処理で最もよく使われます。

`query_row_block_stream` メソッドは、従来のリレーショナルデータベースのように、ブロックを行のシーケンスとして返します。タクシー乗車データでは、返されるデータはリストになり、その各要素はデータの1行を表す別のリストになります。したがって `block[0]` には最初のタクシー乗車のすべてのフィールドが (順番どおりに) 含まれ、`block[1]` には2番目のタクシー乗車のすべてのフィールドを含む行が入ります。以降も同様です。行指向の結果は、通常、表示や変換処理に使われます。

`query_rows_stream` メソッドは、自動的に次のブロックへ進み、1回に1行ずつ返します。これは `query_row_block_stream` の行単位の対応メソッドです。

`query_np_stream` メソッドは、各ブロックを NumPy 配列として返します。すべての結果カラムが同じ NumPy dtype を共有している場合、配列は shape が `(rows, columns)` の2次元になります。型が混在する結果は、1次元の structured array として返されるか、object dtype が使用されます。

`query_df_stream` メソッドは、各 ClickHouse Block を2次元の Pandas DataFrame として返します。以下の例は、`StreamContext` オブジェクトを遅延的にコンテキストとして使用できることを示しています (ただし1回のみ) 。

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

`query_df_arrow_stream` メソッドは、Arrow バッチを Pandas または Polars の DataFrame に変換します。使用するライブラリは `dataframe_library` で選択し、既定値は `"pandas"` です。

最後に、`query_arrow_stream` は ClickHouse の `ArrowStream` レスポンスを `StreamContext` でラップします。各反復では、PyArrow の `RecordBatch` が返されます。

<div id="streaming-examples">
  ### ストリーミングの使用例
</div>

<div id="stream-rows">
  #### 行のストリーミング
</div>

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

<div id="stream-row-blocks">
  #### 行ブロックをストリーミングする
</div>

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

<div id="stream-pandas-dataframes">
  #### Pandas DataFrame をストリーミングする
</div>

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

<div id="stream-arrow-batches">
  #### Arrow バッチをストリーミングする
</div>

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

<div id="async-stream-rows">
  #### 行を非同期でストリームする
</div>

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

<div id="numpy-pandas-and-arrow-queries">
  ## NumPy、Pandas、Arrow クエリ
</div>

ClickHouse Connect には、NumPy、Pandas、Arrow のデータ構造を扱うための専用のクエリメソッドが用意されています。これらのメソッドを使用すると、手動で変換しなくても、クエリ結果をこれらの一般的なデータフォーマットで直接取得できます。

<div id="numpy-queries">
  ### NumPy クエリ
</div>

`query_np` メソッドは、ClickHouse Connect の `QueryResult` ではなく、NumPy 配列としてクエリ結果を返します。

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

<div id="pandas-queries">
  ### Pandas クエリ
</div>

`query_df` メソッドは、ClickHouse Connect の `QueryResult` ではなく、クエリ結果を Pandas の DataFrame として返します。

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

<div id="pyarrow-queries">
  ### PyArrow クエリ
</div>

`query_arrow` メソッドは、ClickHouse の `Arrow` 出力フォーマットを直接使用して PyArrow Table を返します。受け付ける引数は `query`、`parameters`、`settings`、`external_data`、`transport_settings` です。`use_strings` オプションは、ClickHouse の `String` カラムを Arrow の文字列として出力するか、バイナリ値として出力するかを制御します。

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

<div id="arrow-backed-dataframes">
  ### Arrow バックエンド DataFrames
</div>

ClickHouse Connect は、`query_df_arrow` と `query_df_arrow_stream` により、Arrow の結果から DataFrame を効率的に作成できます。これらのメソッドは Python の行オブジェクトを経由する変換を避け、対象のライブラリが対応していれば Arrow バッファを再利用します。

* `query_df_arrow`: ClickHouse の `Arrow` 出力フォーマットを使用してクエリを実行し、DataFrame を返します。
  * `dataframe_library="pandas"` は、`pd.ArrowDtype` を使用する Pandas 2.0 以降の DataFrame を返します。
  * `dataframe_library="polars"` は、`pl.from_arrow` を使って作成された Polars DataFrame を返します。
* `query_df_arrow_stream`: Arrow のバッチを Pandas または Polars の DataFrame としてストリーミングします。

<div id="query-to-arrow-backed-dataframe">
  #### ArrowバックエンドのDataFrameへのクエリ
</div>

```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}")
```

<div id="notes-and-caveats">
  #### 注意事項と留意点
</div>

* Arrow スキーマは ClickHouse によって制御されます。Arrow で直接表現できない型は、バイナリフィールドを含む互換性のある物理型で返される場合があります。アプリケーション固有の変換を適用する前に、`table.schema` または DataFrame の dtype を確認してください。
* Arrow バックエンドの Pandas の結果を利用するには、Pandas 2.0 以降が必要です。
* `use_strings` は、サーバーが `output_format_arrow_string_as_string` をサポートしている場合に、ClickHouse の `String` カラムで Arrow の string フィールドと binary フィールドのどちらを使用するかを制御します。
* `tz_mode="schema"` は、Arrow ベースのクエリメソッドではまだサポートされていません。これらのメソッドは警告を出し、Arrow レスポンスで提供されたタイムゾーンのメタデータを保持します。

<div id="read-formats">
  ## 読み取りフォーマット
</div>

読み取りフォーマットは、`query`、`query_np`、`query_df` が返す値を制御します。raw メソッドや Arrow メソッドには適用されません。これらのメソッドはサーバーの出力フォーマットを直接使用するためです。たとえば、UUID の読み取りフォーマットを `"string"` に設定すると、`uuid.UUID` オブジェクトではなく UUID 文字列が返されます。

任意のフォーマット関数の "data type" 引数にはワイルドカードを含めることができます。フォーマットは小文字 1 つからなる文字列です。`Array`、`Nullable`、`LowCardinality` などのコンテナーラッパーでは、その要素型に対して選択したフォーマットが維持されます。

読み取りフォーマットは、複数のレベルで設定できます。

* `clickhouse_connect.datatypes.format` パッケージで定義されているメソッドを使用して、グローバルに設定できます。これにより、設定したデータ型のフォーマットがすべてのクエリで適用されます。

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

* オプションの `query_formats` 辞書引数を使用すると、クエリ全体に対して指定できます。この場合、指定したデータ型の任意のカラム (またはサブカラム) に、設定されたフォーマットが適用されます。

```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"},
)
```

* 特定の結果カラムに対しては、省略可能な `column_formats` 辞書を使用します。各キーには返されるカラム名を指定します。値には、フォーマット文字列、または ClickHouse の型名からフォーマットへのネストされたマッピングを指定できます。これは Tuples、Maps、その他のコンテナー型で役立ちます。

```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"},
)
```

<div id="read-format-options-python-types">
  ### 読み取りフォーマットオプション (Python 型)
</div>

| ClickHouse Type         | ネイティブ Python 型          | 読み取りフォーマット        | 備考                                                                   |
| ----------------------- | ----------------------- | ----------------- | -------------------------------------------------------------------- |
| Int\[8-64], UInt\[8-32] | int                     | string            |                                                                      |
| UInt64                  | int                     | signed            | Superset は現在、大きな符号なし UInt64 値を処理できません                                |
| \[U]Int\[128,256]       | int                     | string            | Pandas と NumPy の int 値は最大 64 ビットのため、これらは文字列として返すことができます              |
| BFloat16                | float                   | -                 | Python の float はすべて内部的に 64 ビットです                                     |
| Float32                 | float                   | string            | Python の float はすべて内部的に 64 ビットです                                     |
| Float64                 | float                   | string            |                                                                      |
| Decimal                 | decimal.Decimal         | -                 |                                                                      |
| String                  | str                     | bytes             | ClickHouse の String 型のカラムには固有のエンコーディングがないため、可変長のバイナリデータにも使われます       |
| FixedString             | bytes                   | string            | FixedString は固定長のバイト配列ですが、Python の文字列として扱われることもあります                  |
| Enum\[8,16]             | str                     | int               | ネイティブフォーマットではラベルが返されます。`int` は元の整数値を返します。                            |
| Date                    | datetime.date           | int               | 整数フォーマットは 1970-01-01 からの日数を返します。                                     |
| Date32                  | datetime.date           | int               | 整数フォーマットは、より広い範囲の符号付き日オフセットを返します。                                    |
| DateTime                | datetime.datetime       | int               | 整数フォーマットはエポック秒を返します。                                                 |
| DateTime64              | datetime.datetime       | int               | 整数フォーマットは、カラムの精度での ticks を返します。Python の `datetime` はマイクロ秒までに制限されます。  |
| Time                    | datetime.timedelta      | int, string, time | 整数フォーマットは秒を返します。`time` フォーマットは `datetime.time` に収まる値に限られます。          |
| Time64                  | datetime.timedelta      | int, string, time | 整数フォーマットは、カラムの精度での ticks を返します。Python の `timedelta` はマイクロ秒までに制限されます。 |
| IPv4                    | `ipaddress.IPv4Address` | string, int       | IP アドレスは文字列または整数として読み取れます。                                           |
| IPv6                    | `ipaddress.IPv6Address` | string            | IP アドレスは文字列として読み取れ、適切な形式であれば IP アドレスとして挿入できます                        |
| Tuple                   | dict or tuple           | tuple, dict, json | 名前付き Tuple は既定で辞書を返し、名前のない Tuple は tuple を返します。                      |
| Map                     | dict                    | -                 |                                                                      |
| Nested                  | Sequence\[dict]         | -                 |                                                                      |
| UUID                    | uuid.UUID               | string            | UUID は RFC 4122 に準拠した形式の文字列として読み取れます<br />                           |
| JSON                    | dict                    | string            | 既定では Python の辞書が返されます。`string` フォーマットでは JSON 文字列が返されます               |
| Variant                 | object                  | typed             | `typed` は `TypedVariant(value, type_name)` を返すため、元のメンバー型が保持されます。     |
| Dynamic                 | object                  | -                 | 値に格納されている ClickHouse のデータ型に対応する Python 型を返します                        |
| QBit                    | list\[float]            | -                 | インストールされている場合、より高速なビット転置のために NumPy が自動的に使用されます。                      |

<div id="external-data">
  ## 外部データ
</div>

ClickHouse のクエリでは、サポートされている任意の入力フォーマットで外部データを受け取ることができます。クライアントはデータをリクエストの一部として送信し、クエリ内ではそれを一時的な外部テーブルとして参照できます。詳しくは、[ClickHouse external data documentation](/ja/reference/engines/table-engines/special/external-data) を参照してください。Client のクエリメソッドは、`external_data` パラメータを通じて `clickhouse_connect.driver.external.ExternalData` オブジェクトを受け取ります。

| Name       | Type              | Description                                                                       |
| ---------- | ----------------- | --------------------------------------------------------------------------------- |
| file\_path | str               | 外部データの読み込み元となる、ローカルシステム上のファイルへのパスです。`file_path` または `data` のいずれかが必要です             |
| file\_name | str               | 外部データの "file" 名です。指定しない場合は、`file_path` のファイル名部分が使用されます。外部テーブル名は、拡張子を除いたファイル名になります |
| data       | bytes             | 外部データをバイナリ形式で指定します (ファイルから読み込む代わりに使用します) 。`data` または `file_path` のいずれかが必要です       |
| fmt        | str               | データの ClickHouse [入力フォーマット](/ja/reference/formats) です。デフォルトは `TSV` です              |
| types      | str or seq of str | 外部データ内のカラムのデータ型一覧です。文字列の場合、型はカンマで区切る必要があります。`types` または `structure` のいずれかが必要です    |
| structure  | str or seq of str | データ内のカラム名 + データ型の一覧です (例を参照) 。`structure` または `types` のいずれかが必要です                  |
| mime\_type | str               | 省略可能なファイルデータの MIME タイプです。現在、ClickHouse はこの HTTP サブヘッダーを無視します                      |

この例では、外部 CSVファイルをサーバー上に保存されている `directors` テーブルに結合しています:

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

追加の外部データファイルは、コンストラクターと同じパラメーターを受け取る `add_file` メソッドを使って、最初の `ExternalData` オブジェクトに追加できます。HTTP では、すべての外部データは `multi-part/form-data` によるファイルアップロードの一部として送信されます。

chDB バックエンドは外部データをサポートしていません。

<div id="time-zones">
  ## タイムゾーン
</div>

ClickHouse の `DateTime` および `DateTime64` の値は、epoch ベースの数値として送信されます。ClickHouse Connect は、カラムのメタデータ、クエリのオーバーライド、クライアントのタイムゾーンポリシーを使用して、これらを Python の `datetime` オブジェクトに変換します。

クライアントには、互いに独立した 2 つのタイムゾーンオプションがあります。

* `tz_source` は、明示的なタイムゾーンメタデータを持たないカラムに対するフォールバックのタイムゾーンを選択します。
  * `"auto"` がデフォルトです。クライアントが夏時間の切り替えをまたいでも安全に解決できる場合はサーバータイムゾーンを使用し、そうでない場合はローカルタイムゾーンを使用します。
  * `"server"` は常にサーバータイムゾーンを使用します。
  * `"local"` は常にローカルプロセスのタイムゾーンを使用します。
* `tz_mode` はタイムゾーン対応を制御します。
  * `"naive_utc"` がデフォルトです。UTC および UTC 相当の結果は、後方互換性のため、naive な `datetime` オブジェクトとして返されます。
  * `"aware"` は UTC の tzinfo を保持し、タイムゾーン対応の UTC 値を返します。
  * `"schema"` は、カラム型でタイムゾーンが宣言されている場合にのみタイムゾーン対応の値を返し、タイムゾーン指定のない `DateTime`/`DateTime64` カラムには naive な値を返します。

通常の `"naive_utc"` および `"aware"` クエリでは、有効なタイムゾーンは次の順序で選択されます。

1. カラムごとの `column_tzs` オーバーライド。
2. ClickHouse のカラム型に含まれるタイムゾーンメタデータ。
3. クエリ全体に適用される `query_tz` オーバーライド。
4. HTTP レスポンスとともに返されるタイムゾーン情報。
5. `tz_source` で選択されたフォールバック。

`tz_mode="schema"` はクエリおよびフォールバックのタイムゾーンを無視しますが、明示的な `column_tzs` オーバーライドは引き続き優先されます。

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

タイムゾーン名は、標準ライブラリの `zoneinfo` モジュールで解決されます。Windows へのインストールでは `tzdata` が自動的に自動的に含まれます。IANA タイムゾーンデータベースを含まない最小構成の Linux イメージでは、`clickhouse-connect[tzdata]` をインストールしてください。

Pandas の結果では、`DateTime` は `datetime64[s]`、`DateTime64(3)` は `datetime64[ms]` というように、各 ClickHouse 型本来の精度が保持されます。Arrow バックエンドの DataFrame メソッド `query_df_arrow` と `query_df_arrow_stream` は、まだ `tz_mode="schema"` に対応しておらず、これが指定されると警告を出します。`query_arrow` と `query_arrow_stream` は、Arrow レスポンスのタイムゾーン メタデータを変更せずにそのまま返します。
