FORMAT Native: это query, query_np, query_df, их варианты с потоковой передачей блоков и строк, а также вставки, включая insert_df. Методы Arrow используют FORMAT Arrow и не затрагиваются, равно как и raw-запросы, raw-вставки и форматы, отличные от Native.
Кодек является экспериментальным и включается явно. По умолчанию используется кодек на Python.
Установка
Скомпилированный кодек поставляется в виде отдельного wheel-пакетаclickhouse-connect-core, который предоставляет модуль расширения _ch_core. Для оценки установите кодек вместе с PyArrow:
query_np, query_df, их потоковым вариантам и query(..., use_numpy=True). Без PyArrow native_codec="rust" выводит предупреждение в журнал и выполняет такие запросы с кодеком на Python, а native_codec="rust_strict" вместо этого вызывает NotSupportedError.
Дополнение rust само по себе остаётся компактным для приложений, которые используют стандартные результаты в виде строк Python, потоки блоков по строкам или по столбцам, а также вставки без запроса вывода в NumPy или Pandas. Эти пути не требуют PyArrow:
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 — как двоичное значение.