FORMAT Native géré par le client, ce qui couvre query, query_np, query_df, leurs variantes de streaming par bloc et par ligne, ainsi que les insertions, y compris insert_df. Les méthodes Arrow utilisent FORMAT Arrow et ne sont donc pas concernées, pas plus que les requêtes raw, les insertions raw et les formats non natifs.
Le codec est expérimental et son utilisation est optionnelle. Le codec Python reste celui utilisé par défaut.
Installation
Le codec compilé est distribué sous la forme d’un wheel distinct nomméclickhouse-connect-core, qui fournit le module d’extension _ch_core. Pour l’évaluation, installez le codec et PyArrow ensemble :
query_np, query_df, leurs variantes en streaming, ainsi que query(..., use_numpy=True). Sans PyArrow, native_codec="rust" émet un avertissement et exécute ces requêtes avec le codec Python. native_codec="rust_strict", lui, lève une erreur NotSupportedError.
L’extra rust seul reste léger pour les applications qui utilisent les résultats en lignes Python standard, les flux de blocs par ligne ou par colonne, ainsi que les insertions, sans demander de sortie NumPy ou Pandas. Ces chemins ne nécessitent pas PyArrow :
NotSupportedError indiquant cette commande d’installation.
Activation du codec
Sélectionnez le codec via l’option clientnative_codec :
La valeur par défaut peut également être définie via le paramètre commun
native_codec ou la variable d’environnement CLICKHOUSE_CONNECT_NATIVE_CODEC. L’ordre de préséance est le suivant : l’argument nommé du client, puis le paramètre commun, puis la variable d’environnement.
L’option est ignorée pour les clients interface="chdb", qui utilisent toujours le codec Python.
Quand utiliser le codec Rust
Le codec Rust est particulièrement utile pour les résultats DataFrame volumineux comportant du texte, des conteneurs et des types complexes tels queString, LowCardinality, Map, Array, JSON, Decimal et UUID. Il peut également bénéficier aux flux volumineux de blocs de lignes et de colonnes, aux charges de travail de requêtes concurrentes et aux insertions en masse.
Les petits résultats et les requêtes limitées par le réseau ne montreront sans doute que peu de différence. Les résultats numériques plats empruntent déjà des chemins d’accès en masse efficaces dans le codec Python : le gain y sera donc lui aussi plus limité.
Les appels query() bufferisés portant sur des résultats très larges ou entièrement numériques peuvent actuellement s’avérer plus lents et consommer davantage de mémoire de pointe avec le codec Rust. Pour ces charges de travail, privilégiez query_df, query_row_block_stream ou query_column_block_stream. Le streaming permet de maintenir la mémoire bornée.
Évaluez les performances sur votre propre charge de travail avant d’adopter le codec. Utilisez native_codec="rust_strict" pendant vos mesures afin qu’une option non prise en charge ou une dépendance manquante lève une erreur au lieu de rediriger silencieusement la requête vers Python.
Règles de fallback
Les décisions de fallback sont prises avant que le moindre octet ne soit lu ou envoyé : aucun changement de codec ne survient donc en cours de stream. Pour les requêtes, le choix intervient avant la consommation du response body. Pour les insertions, l’encodeur Rust n’est retenu que si tous les types de colonnes sont pris en charge ; sinon, l’insertion s’exécute intégralement avec le codec Python. Lorsquenaive_datetime_insert="server" est actif, rust route vers le codec Python toute insertion contenant une colonne DateTime ou DateTime64, afin que la timezone déclarée de la colonne ou la server timezone soit appliquée. rust_strict rejette cette combinaison. Le mode par défaut naive_datetime_insert="local" continue d’utiliser l’encodeur Rust.
Les requêtes de metadata internes au driver, y compris les statements de reflection du dialect SQLAlchemy, passent toujours par le codec Python, de façon silencieuse, quel que soit le mode.
Les payloads Native malformés détectés par le codec Rust lèvent DataError.
Versioning
clickhouse-connect-core est versionné indépendamment de clickhouse-connect. Le driver déclare une plage de compatibilité via l’extra rust, et le module expose une version de l’API de binding que le driver vérifie lorsqu’un codec Rust est sélectionné. Si le wheel installé est trop ancien pour le driver, la création du client lève une NotSupportedError indiquant la commande d’upgrade à exécuter :
clickhouse-connect-core et peuvent être obtenues par une simple mise à niveau vers un wheel core compatible. Les modifications de l’intégration Rust du driver nécessitent en revanche une mise à niveau de clickhouse-connect.
Différences de comportement connues
Le codec Rust vise une parité cellule par cellule avec le codec Python. Les différences suivantes sont connues.- Les résultats de
query_npetquery_dfpour les colonnesVariantcontiennent des objets Python simples plutôt que des valeurs scalaires numpy. Les valeurs sont identiques, mais les types de cellules diffèrent. - Les valeurs
DynamiccontenantTime64sont matérialisées sous la formedatetime.timedeltadans les résultats Rust dequery_npetquery_df. Aux échelles 0, 3, 6 et 9, les valeurs sont égales aux cellulesnumpy.timedelta64du codec Python, mais les types de cellules diffèrent. Aux autres échelles, le codec Rust renvoiedatetime.timedeltaalors que le codec Python lèveProgrammingError, car NumPy n’a pas d’unité correspondante. Les metadata des membres Dynamic ne sont pas exposées au driver après le décodage Rust : utilisez doncnative_codec="python"lorsque les types de cellules NumPy ou la validation des échelles non prises en charge sont nécessaires. - Pour
query_df, le codec Python peut convertir en chaîne les valeurs Compound stockées dans les shared data JSON. Le codec Rust renvoie des objets décodés, ce qui correspond aux résultats dequery_npdes deux codecs. - Une alternative
LowCardinalityplacée dans un conteneur qui se matérialise cellule par cellule, commeArray(Variant(...)), produit des cellules de valeurs égales qui ne partagent pas l’identité d’objet par slot de dictionary observée avec le codec Python. - Les colonnes
Nullable(Tuple(...))comportant un ou plusieurs elements sont décodées correctement par le codec Rust. Le codec Python interprète mal ce layout ; le résultat Rust constitue donc le comportement de référence. Les deux codecs prennent en chargeNullable(Tuple()). rust_strictrejette les options de query que le chemin Rust n’implémente pas, telles que desquery_formatscustom par query, plutôt que de modifier silencieusement le comportement.- Les erreurs de conversion et de validation lors d’une insertion Rust peuvent lever
DataErrorlà où le codec Python lèveValueError, et le texte du message peut différer. Exemples : valeursTimeetTime64invalides, adresses IPv6, dimensions QBit, longueursFixedString, chaînesFloat64et tentatives d’insertion d’elements dans une colonneTuple(). - L’encodeur Rust rejette
b""pourFixedString(N)ainsi que les chaînes numériques telles que"2"pour les colonnes integer. Le codec Python, lui, complète par des zéros une valeurFixedStringvide et convertit les chaînes numériques. - Le codec Rust décode certaines valeurs de variante partagée
Dynamicvers leurs types Python là où le codec Python laisse la valeur en raw bytes. Par exemple, uneDatestockée peut être renvoyée commedatetime.datepar Rust et comme valeur binaire par Python.