> ## 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.

> Insertion avancée avec ClickHouse Connect

# Insertion avancée

<div id="inserting-data-with-clickhouse-connect--advanced-usage">
  ## Insertion de données avec ClickHouse Connect : utilisation avancée
</div>

<div id="insertcontexts">
  ### InsertContexts
</div>

ClickHouse Connect exécute les insertions au format Native, c’est-à-dire les méthodes `insert` et `insert_df`, dans un `InsertContext`. Les méthodes `insert_arrow`, `insert_df_arrow` et `raw_insert` envoient directement leurs payloads et n’en utilisent pas. L’`InsertContext` inclut toutes les valeurs transmises comme arguments à la méthode client `insert`. De plus, lors de la création initiale d’un `InsertContext`, ClickHouse Connect récupère les types de données des colonnes à insérer, nécessaires à des insertions efficaces au format Native. En réutilisant l’`InsertContext` pour plusieurs insertions, cette « pré-requête » est évitée, ce qui rend les insertions plus rapides et plus efficaces.

Il est possible d’obtenir un `InsertContext` à l’aide de la méthode client `create_insert_context`. Cette méthode prend les mêmes arguments que la fonction `insert`, à l’exception de `context` lui-même. Notez que seule la propriété `data` des `InsertContext` doit être modifiée en vue d’une réutilisation. Cela correspond à son objectif : fournir un objet réutilisable pour des insertions répétées de nouvelles données dans la même table.

```python theme={null}
test_data = [[13, "v1", "v2"], [79, "v3", "v4"]]
ic = client.create_insert_context(table="test_table", data=test_data)
client.insert(context=ic)
assert client.command("SELECT count() FROM test_table") == 2

new_data = [[101, "v5", "v6"], [113, "v7", "v8"]]
ic.data = new_data
client.insert(context=ic)
qr = client.query("SELECT * FROM test_table ORDER BY key DESC")
assert qr.row_count == 4
assert qr.first_row[0] == 113
```

`InsertContext`s incluent un état mutable mis à jour pendant le processus d’insertion ; ils ne sont donc pas thread-safe.

<div id="write-formats">
  ### Formats d'écriture
</div>

Les formats d'écriture sont implémentés pour un nombre limité de types. Dans la plupart des cas, ClickHouse Connect détermine automatiquement le format d'écriture approprié pour une colonne à partir de sa première valeur de données non nulle. Par exemple, lorsque la première valeur d'une colonne `DateTime` est un entier, le client la traite comme un nombre de secondes depuis l'`époque Unix`.

Il n'est généralement pas nécessaire de remplacer un format d'écriture, mais les méthodes de `clickhouse_connect.datatypes.format` permettent d'en définir un globalement. Les wrappers de conteneur tels que `Array`, `Nullable` et `LowCardinality` conservent le comportement de mise en forme du type d'élément.

<div id="write-format-options">
  #### Options de format d'écriture
</div>

| Type ClickHouse         | Type Python natif       | Formats d'écriture | Commentaires                                                                                                                                                       |
| ----------------------- | ----------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Int\[8-64], UInt\[8-32] | int                     |                    |                                                                                                                                                                    |
| UInt64                  | int                     |                    |                                                                                                                                                                    |
| \[U]Int\[128,256]       | int                     |                    |                                                                                                                                                                    |
| BFloat16                | float                   |                    |                                                                                                                                                                    |
| Float32                 | float                   |                    |                                                                                                                                                                    |
| Float64                 | float                   |                    |                                                                                                                                                                    |
| Decimal                 | decimal.Decimal         |                    |                                                                                                                                                                    |
| String                  | str or bytes            |                    | Une colonne doit contenir de manière cohérente soit du texte, soit des octets.                                                                                     |
| FixedString             | bytes                   | string             | Les valeurs de chaîne sont complétées par des octets nuls. Les octets vides sont écrits comme des octets tous nuls.                                                |
| Enum\[8,16]             | str or int              |                    | Insérez les libellés sous forme de chaînes ou leurs valeurs entières sous-jacentes.                                                                                |
| Date                    | datetime.date           | int                | Les valeurs entières sont interprétées comme des jours depuis 1970-01-01.                                                                                          |
| Date32                  | datetime.date           | int                | Les valeurs entières sont interprétées comme des décalages signés en jours.                                                                                        |
| DateTime                | datetime.datetime       | int                | Les valeurs entières sont interprétées comme des secondes depuis l'époque Unix.                                                                                    |
| DateTime64              | datetime.datetime       | int                | Les valeurs entières sont interprétées comme des ticks selon la précision de la colonne.                                                                           |
| Time                    | datetime.timedelta      | int, string, time  | Les valeurs entières sont interprétées comme des secondes.                                                                                                         |
| Time64                  | datetime.timedelta      | int, string, time  | Les valeurs entières sont interprétées comme des ticks selon la précision de la colonne.                                                                           |
| IPv4                    | `ipaddress.IPv4Address` | string             | Des chaînes au format correct peuvent être insérées comme adresses IPv4                                                                                            |
| IPv6                    | `ipaddress.IPv6Address` | string             | Des chaînes au format correct peuvent être insérées comme adresses IPv6                                                                                            |
| Tuple                   | dict or tuple           |                    |                                                                                                                                                                    |
| Map                     | dict                    |                    |                                                                                                                                                                    |
| Nested                  | Sequence\[dict]         |                    |                                                                                                                                                                    |
| UUID                    | uuid.UUID               | string             | Des chaînes au format correct peuvent être insérées comme UUID ClickHouse                                                                                          |
| JSON                    | dict                    | string             | Les dictionnaires et les chaînes contenant un objet JSON sont pris en charge. Le type legacy `Object('json')` n'est pas pris en charge.                            |
| Variant                 | object                  |                    | Les valeurs utilisent la sérialisation native du type membre. Utilisez `clickhouse_connect.datatypes.dynamic.typed_variant` lorsque les types Python sont ambigus. |
| Dynamic                 | object                  |                    | Les valeurs sont actuellement insérées à partir de leur représentation sous forme de chaîne.                                                                       |
| QBit                    | Sequence\[float]        |                    | NumPy est utilisé automatiquement pour une transposition des bits plus rapide lorsqu’il est installé.                                                              |

<div id="specialized-insert-methods">
  ### Méthodes d’insertion spécialisées
</div>

ClickHouse Connect fournit des méthodes d’insertion spécialisées pour les formats de données courants :

* `insert_df` -- Insère un Pandas DataFrame comme données Native orientées colonnes. Il prend également en charge des noms/types de colonnes explicites ou un `InsertContext` réutilisable.
* `insert_arrow` -- Insère une PyArrow Table à l’aide du format d’entrée Arrow de ClickHouse.
* `insert_df_arrow` -- Insère un Pandas DataFrame adossé à Arrow ou un Polars DataFrame. Les colonnes Pandas doivent toutes utiliser des Dtype adossés à Arrow.

Les trois méthodes acceptent `database`, `settings` et les `transport_settings` HTTP par requête.

<Note>
  Un tableau NumPy est une Sequence of Sequences valide et peut être utilisé comme argument `data` avec la méthode `insert` principale ; une méthode spécialisée n’est donc pas nécessaire.
</Note>

<div id="pandas-dataframe-insert">
  #### Insertion de DataFrame Pandas
</div>

```python theme={null}
import clickhouse_connect
import pandas as pd

client = clickhouse_connect.get_client()

df = pd.DataFrame({
    "id": [13, 79],
    "name": ["user_1", "user_2"],
    "age": [25, 30],
})

client.insert_df("users", df)
```

<div id="pyarrow-table-insert">
  #### Insertion d’une table PyArrow
</div>

```python theme={null}
import clickhouse_connect
import pyarrow as pa

client = clickhouse_connect.get_client()

arrow_table = pa.table({
    "id": [13, 79],
    "name": ["user_1", "user_2"],
    "age": [25, 30],
})

client.insert_arrow("users", arrow_table)
```

<div id="arrow-backed-dataframe-insert-pandas-2">
  #### Insertion d’un DataFrame adossé à Arrow (pandas 2.x)
</div>

```python theme={null}
import clickhouse_connect
import pandas as pd

client = clickhouse_connect.get_client()

# Convert to Arrow-backed dtypes for better performance
df = pd.DataFrame({
    "id": [13, 79],
    "name": ["user_1", "user_2"],
    "age": [25, 30],
}).convert_dtypes(dtype_backend="pyarrow")

client.insert_df_arrow("users", df)
```

<div id="create-table-from-pyarrow-schema">
  ### Créer une table à partir d’un schéma PyArrow
</div>

`create_table_from_arrow_schema` génère une instruction `CREATE TABLE` à partir de champs scalaires Arrow courants. La correspondance couvre les entiers signés et non signés, les valeurs à virgule flottante, les booléens, les chaînes, les dates et les horodatages. Elle crée intentionnellement des colonnes ClickHouse non `Nullable` et lève une exception `TypeError` pour les types Arrow non pris en charge. Passez en revue le DDL généré avant de l’exécuter.

```python theme={null}
import clickhouse_connect
import pyarrow as pa

from clickhouse_connect.driver.ddl import create_table_from_arrow_schema

client = clickhouse_connect.get_client()
schema = pa.schema(
    [
        ("id", pa.uint32()),
        ("name", pa.string()),
        ("event_time", pa.timestamp("ms", tz="UTC")),
    ]
)
ddl = create_table_from_arrow_schema(
    table_name="arrow_events",
    schema=schema,
    engine="MergeTree",
    engine_params={"ORDER BY": "id"},
)
client.command(ddl)
```

<div id="time-zones">
  ### Fuseaux horaires
</div>

Lors de l’insertion d’objets Python `datetime` dans des colonnes `DateTime` ou `DateTime64`, ClickHouse Connect les convertit en valeurs d’époque Unix.

<div id="timezone-aware-datetime-objects">
  #### Objets datetime avec informations de fuseau horaire
</div>

Les objets avec informations de fuseau horaire préservent l’instant représenté. Il n’est pas nécessaire que le fuseau horaire source corresponde à celui déclaré sur la colonne ClickHouse.

```python theme={null}
from datetime import datetime, timezone
from zoneinfo import ZoneInfo

client.command("CREATE TABLE events (event_time DateTime) ENGINE Memory")

data = [
    [datetime(2023, 6, 15, 10, 30, tzinfo=timezone.utc)],
    [datetime(2023, 6, 15, 10, 30, tzinfo=ZoneInfo("America/Denver"))],
    [datetime(2023, 6, 15, 10, 30, tzinfo=ZoneInfo("Asia/Tokyo"))],
]

client.insert("events", data, column_names=["event_time"])
results = client.query(
    "SELECT event_time FROM events ORDER BY event_time",
    query_tz="UTC",
    tz_mode="aware",
)
assert [row[0].hour for row in results.result_rows] == [1, 10, 16]
```

<Note>
  ClickHouse Connect utilise le module `zoneinfo` de la bibliothèque standard. Le driver ne dépend plus de `pytz`.
</Note>

<div id="timezone-naive-datetime-objects">
  #### Objets `datetime` sans fuseau horaire
</div>

Le paramètre global `naive_datetime_insert` contrôle l'insertion d'objets Python natifs contenant des valeurs `datetime` sans fuseau horaire. Il s'applique également aux chaînes ISO sans fuseau horaire acceptées par les colonnes `DateTime64`.

* `"local"` est la valeur par défaut dans la version 1.x. Python interprète la valeur dans le fuseau horaire du processus lors de l'appel à `.timestamp()`. Cela préserve le comportement existant.
* `"server"` interprète la valeur comme une heure locale dans le fuseau horaire déclaré par la colonne `DateTime` ou `DateTime64`. Si la colonne n'a pas de fuseau horaire, le fuseau horaire du serveur communiqué lors de la connexion du client est utilisé.

Définissez l'option avant une insertion. Elle est lue lors de la sérialisation de chaque colonne d'insertion native contenant des objets Python `datetime` ou des chaînes ISO `DateTime64` ; la modification s'applique donc aux clients existants et aux contextes d'insertion réutilisables.

```python theme={null}
from datetime import datetime

from clickhouse_connect import common

common.set_setting("naive_datetime_insert", "server")

naive_time = datetime(2023, 6, 15, 10, 30)
client.insert("events", [[naive_time]], column_names=["event_time"])
```

Avec `"server"`, ClickHouse Connect associe le `tzinfo` cible avant de convertir la valeur en époque Unix. Pour les fuseaux horaires IANA, il suit les règles de la bibliothèque standard pour les transitions vers ou depuis l’heure d’été. En cas de chevauchement à l’automne, la valeur `fold` du `datetime` est utilisée. Par défaut, `fold=0` sélectionne le décalage avant la transition, tandis que `fold=1` sélectionne celui après la transition. En cas de lacune au printemps, la même sélection de décalage est utilisée, sans rejet ni normalisation.

Les heures locales inexistantes lors d’une lacune printanière peuvent ne pas effectuer d’aller-retour via un paramètre de requête en mode wall, car l’analyse de texte de ClickHouse peut sélectionner un décalage différent. Utilisez un `datetime` avec fuseau horaire ou une heure locale valide lorsque l’instant est important.

L’option s’applique uniquement aux insertions natives d’objets Python `datetime` et aux chaînes ISO sans fuseau horaire acceptées par `DateTime64`. Les colonnes NumPy et Pandas de type `datetime64` sans fuseau horaire conservent leur conversion existante des heures locales UTC.

Pour représenter un instant précis indépendamment de l’un ou l’autre mode, associez le fuseau horaire souhaité ou fournissez explicitement un entier époque Unix.

```python theme={null}
from datetime import datetime, timezone

utc_time = datetime(2023, 6, 15, 10, 30, tzinfo=timezone.utc)
client.insert("events", [[utc_time]], column_names=["event_time"])

naive_time = datetime(2023, 6, 15, 10, 30)
epoch_timestamp = int(naive_time.replace(tzinfo=timezone.utc).timestamp())
client.insert("events", [[epoch_timestamp]], column_names=["event_time"])
```

Les paramètres de requête `datetime` sans fuseau horaire utilisent le paramètre distinct `naive_datetime_binding`. Son mode par défaut, `"wall"`, envoie les champs tels quels, sans conversion vers le fuseau horaire local de l'hôte. Consultez la section [Argument Parameters](/fr/integrations/language-clients/python/driver-api#parameters-argument).

<div id="datetime-columns-with-timezone-metadata">
  #### Colonnes DateTime avec métadonnées de fuseau horaire
</div>

Les colonnes ClickHouse peuvent déclarer des métadonnées de fuseau horaire, par exemple `DateTime('America/Denver')` ou `DateTime64(3, 'Asia/Tokyo')`. Ces métadonnées déterminent la manière dont les valeurs sont affichées lors de l’exécution d’une requête.

Lors de l’insertion d’une valeur avec fuseau horaire, ClickHouse Connect préserve l’instant représenté. Pour une valeur sans fuseau horaire, le paramètre `naive_datetime_insert` détermine si le fuseau horaire du processus ou celui de la colonne est utilisé. Lors d’une requête, le résultat utilise le fuseau horaire de la colonne, sauf si une substitution par colonne est fournie via l’argument `column_tzs`. L’argument `query_tz` ne remplace pas le fuseau horaire déclaré pour une colonne.

```python theme={null}
from datetime import datetime
from zoneinfo import ZoneInfo

client.command(
    "CREATE TABLE events_with_timezone "
    "(event_time DateTime('America/Los_Angeles')) "
    "ENGINE Memory"
)

data = datetime(2023, 6, 15, 10, 30, tzinfo=ZoneInfo("America/New_York"))
client.insert("events_with_timezone", [[data]], column_names=["event_time"])

result = client.query("SELECT event_time FROM events_with_timezone")
returned = result.first_row[0]
assert returned.hour == 7
assert returned.tzinfo == ZoneInfo("America/Los_Angeles")
```

<div id="file-inserts">
  ## Insertions de fichiers
</div>

`clickhouse_connect.driver.tools.insert_file` transmet en flux un fichier local vers une table existante et confie l’analyse à ClickHouse.

| Paramètre      | Type           | Par défaut                  | Description                                                                                                                               |
| -------------- | -------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `client`       | `Client`       | Obligatoire                 | Client synchrone utilisé pour l’insertion.                                                                                                |
| `table`        | str            | Obligatoire                 | Table cible simple ou qualifiée par la base de données.                                                                                   |
| `file_path`    | str            | Obligatoire                 | Chemin local vers le fichier d’entrée.                                                                                                    |
| `fmt`          | str            | `"CSV"` ou `"CSVWithNames"` | Format d’entrée. Par défaut, `"CSV"` lorsque `column_names` est fourni, et `"CSVWithNames"` sinon.                                        |
| `column_names` | Sequence\[str] | `None`                      | Colonnes représentées par le fichier. Non requis pour les formats qui incluent les noms.                                                  |
| `database`     | str            | `None`                      | Base de données cible lorsque la table n’est pas qualifiée.                                                                               |
| `settings`     | dict           | `None`                      | Voir [l’argument Settings](/fr/integrations/language-clients/python/driver-api#settings-argument-1).                                      |
| `compression`  | str            | `None`                      | Compression existante du fichier, telle que `"zstd"`, `"lz4"` ou `"gzip"`. gzip est inféré à partir des noms de fichier `.gz` et `.gzip`. |

Les paramètres du format d’entrée, tels que `input_format_allow_errors_ratio` et `input_format_allow_errors_num`, peuvent être transmis via `settings`.

```python theme={null}
import clickhouse_connect
from clickhouse_connect.driver.tools import insert_file

client = clickhouse_connect.get_client()
insert_file(
    client,
    "example_table",
    "my_data.csv",
    settings={
        "input_format_allow_errors_ratio": 0.2,
        "input_format_allow_errors_num": 5,
    },
)
```

Pour un `AsyncClient`, utilisez `await` avec `insert_file_async` en passant les mêmes arguments :

```python theme={null}
from clickhouse_connect.driver.tools import insert_file_async

await insert_file_async(async_client, "example_table", "my_data.csv")
```

L'utilitaire asynchrone lit le fichier dans un thread worker avant d'attendre `raw_insert`, de sorte que le contenu du fichier reste en mémoire.
