Skip to main content
ClickHouse Connect может декодировать результаты запросов и кодировать вставки с помощью скомпилированного кодека на Rust вместо реализации на Python и Cython, используемой по умолчанию. Кодек на Rust применяется только к управляемому клиентом трафику FORMAT Native: это query, query_np, query_df, их варианты с потоковой передачей блоков и строк, а также вставки, включая insert_df. Методы Arrow используют FORMAT Arrow и не затрагиваются, равно как и raw-запросы, raw-вставки и форматы, отличные от Native. Кодек является экспериментальным и включается явно. По умолчанию используется кодек на Python.

Установка

Скомпилированный кодек поставляется в виде отдельного wheel-пакета clickhouse-connect-core, который предоставляет модуль расширения _ch_core. Для оценки установите кодек вместе с PyArrow:
В версии 1.8 любой путь на Rust, формирующий вывод в NumPy или Pandas, требует PyArrow. Это относится к query_np, query_df, их потоковым вариантам и query(..., use_numpy=True). Без PyArrow native_codec="rust" выводит предупреждение в журнал и выполняет такие запросы с кодеком на Python, а native_codec="rust_strict" вместо этого вызывает NotSupportedError. Дополнение rust само по себе остаётся компактным для приложений, которые используют стандартные результаты в виде строк Python, потоки блоков по строкам или по столбцам, а также вставки без запроса вывода в NumPy или Pandas. Эти пути не требуют PyArrow:
Кодек, его упаковка и набор зависимостей являются экспериментальными. Для будущего выпуска рассматривается более компактная зависимость для совместимости с Arrow. Если выбран кодек на Rust, а скомпилированный модуль не установлен, при создании клиента возникает ошибка NotSupportedError с указанием этой команды установки.

Включение кодека

Выберите кодек с помощью клиентской опции native_codec:
Допустимые значения: Значение по умолчанию также можно задать через общую настройку native_codec или переменную окружения CLICKHOUSE_CONNECT_NATIVE_CODEC. Наивысший приоритет имеет именованный аргумент клиента, затем общая настройка и, наконец, переменная окружения. Для клиентов с interface="chdb" этот параметр игнорируется — они всегда используют кодек на Python.

Когда использовать кодек на Rust

Кодек на Rust наиболее полезен для больших результатов в виде DataFrame с текстовыми, контейнерными и составными типами, такими как String, LowCardinality, Map, Array, JSON, Decimal и UUID. Он также может ускорить работу с большими потоками блоков строк и столбцов, параллельными рабочими нагрузками из запросов и массовыми вставками. Для небольших результатов и запросов, ограниченных пропускной способностью сети, разница может быть незначительной. Простые числовые результаты уже обрабатываются эффективными пакетными путями в кодеке на Python, поэтому выигрыш для них тоже будет меньше. Буферизованные вызовы query() для очень широких или полностью числовых результатов сейчас могут работать медленнее и давать более высокое пиковое потребление памяти при использовании кодека на Rust. Для таких рабочих нагрузок предпочтительнее query_df, query_row_block_stream или query_column_block_stream. Стриминг удерживает потребление памяти в заданных пределах. Прежде чем переходить на этот кодек, протестируйте его на собственной рабочей нагрузке. При замерах используйте native_codec="rust_strict", чтобы неподдерживаемая опция или отсутствующая зависимость приводили к исключению, а не к незаметному перенаправлению запроса в Python.

Правила fallback

Решение о fallback принимается до того, как будут прочитаны или отправлены какие-либо байты, поэтому переключение кодека посреди потока невозможно. Для запросов выбор делается до чтения тела ответа. Для вставок кодировщик на Rust выбирается только в том случае, если поддерживаются все типы столбцов; иначе вся вставка выполняется на кодеке на Python. Когда активен режим naive_datetime_insert="server", режим rust направляет вставку, содержащую хотя бы один столбец типа DateTime или DateTime64, на кодек на Python, чтобы применялся объявленный timezone столбца или server timezone. rust_strict отклоняет такое сочетание. Режим по умолчанию naive_datetime_insert="local" по-прежнему использует кодировщик на Rust. Внутренние запросы драйвера к метаданным, включая команды reflection диалекта SQLAlchemy, всегда используют кодек на Python — незаметно для пользователя и во всех режимах. Некорректные полезные нагрузки Native, обнаруженные кодеком Rust, приводят к ошибке DataError.

Versioning

clickhouse-connect-core версионируется независимо от clickhouse-connect. Драйвер объявляет совместимый диапазон версий через дополнение rust, а модуль экспортирует версию binding API, которую драйвер проверяет при выборе кодека на Rust. Если установленный wheel-пакет слишком стар для драйвера, при создании клиента возникает NotSupportedError с указанием команды обновления:
Исправления и повышение производительности скомпилированного кодека выходят в составе релизов clickhouse-connect-core, и их можно получить, обновив wheel-пакет core до совместимой версии. Изменения в интеграции драйвера с Rust требуют обновления clickhouse-connect.

Известные различия в поведении

Кодек на Rust нацелен на побитовое совпадение с кодеком на Python вплоть до каждой ячейки. Ниже перечислены известные различия.
  • Результаты query_np и query_df для столбцов Variant содержат обычные объекты Python, а не скалярные значения numpy. Сами значения совпадают, различаются типы ячеек.
  • Значения Dynamic, содержащие Time64, материализуются как datetime.timedelta в результатах query_np и query_df кодека на Rust. При scale 0, 3, 6 и 9 значения совпадают с ячейками numpy.timedelta64 кодека на Python, но типы ячеек различаются. При других значениях scale кодек на Rust возвращает datetime.timedelta, тогда как кодек на Python выбрасывает ProgrammingError, поскольку в NumPy нет подходящей единицы измерения. Метаданные членов Dynamic после декодирования на Rust драйверу не передаются, поэтому используйте native_codec="python", если нужны типы ячеек NumPy или проверка неподдерживаемых значений scale.
  • Для query_df кодек на Python может преобразовывать в строки составные значения, хранящиеся в общих данных JSON. Кодек на Rust возвращает декодированные объекты, что соответствует результатам query_np обоих кодеков.
  • Альтернатива LowCardinality внутри контейнера, который материализуется поячеечно, например Array(Variant(...)), даёт равные по значению ячейки, которые не разделяют идентичность объекта на слот словаря, характерную для кодека на Python.
  • Столбцы Nullable(Tuple(...)) с одним или несколькими элементами кодек на Rust декодирует корректно. Кодек на Python читает такую структуру неверно, поэтому эталонным считается результат Rust. Оба кодека поддерживают Nullable(Tuple()).
  • rust_strict отклоняет параметры запроса, не реализованные в Rust-пути, например пользовательские query_formats для отдельного запроса, вместо того чтобы незаметно менять поведение.
  • Ошибки преобразования и валидации при вставке в Rust могут приводить к DataError там, где кодек на Python выбрасывает ValueError, при этом текст сообщения может отличаться. Например: недопустимые значения Time и Time64, IPv6-адреса, размерности QBit, длины FixedString, строки Float64, а также попытки вставить элементы в столбец Tuple().
  • Кодировщик на Rust отклоняет b"" для FixedString(N) и числовые строки вида "2" для целочисленных столбцов. Кодек на Python дополняет пустое значение FixedString нулями и приводит числовые строки к нужному типу.
  • Кодек на Rust декодирует некоторые значения общих вариантов Dynamic в соответствующие типы Python, тогда как кодек на Python оставляет значение в виде сырых байтов. Например, сохранённое значение Date из Rust вернётся как datetime.date, а из Python — как двоичное значение.
Последнее изменение 26 сентября 2026 г.