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

> Inserción avanzada con ClickHouse Connect

# Inserción avanzada

<div id="inserting-data-with-clickhouse-connect--advanced-usage">
  ## Inserción de datos con ClickHouse Connect: uso avanzado
</div>

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

ClickHouse Connect ejecuta las inserciones en Native format, los métodos `insert` e `insert_df`, dentro de un `InsertContext`. Los métodos `insert_arrow`, `insert_df_arrow` y `raw_insert` envían sus payloads directamente y no usan ninguno. El `InsertContext` incluye todos los valores enviados como argumentos al método `insert` del cliente. Además, cuando se crea un `InsertContext`, ClickHouse Connect recupera los tipos de datos de las columnas de inserción necesarios para realizar inserciones eficientes en Native format. Al reutilizar el `InsertContext` para varias inserciones, se evita esta "consulta previa" y las inserciones se ejecutan de forma más rápida y eficiente.

Se puede obtener un `InsertContext` mediante el método `create_insert_context` del cliente. El método acepta los mismos argumentos que la función `insert`, excepto `context` en sí. Tenga en cuenta que, para reutilizarlo, solo debe modificarse la propiedad `data` de los `InsertContext`. Esto concuerda con su propósito: proporcionar un objeto reutilizable para inserciones repetidas de datos nuevos en la misma tabla.

```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 incluyen un estado mutable que se actualiza durante el proceso de inserción, así que no es seguro usarlos desde varios hilos.

<div id="write-formats">
  ### Formatos de escritura
</div>

Los formatos de escritura están implementados para un número limitado de tipos. En la mayoría de los casos, ClickHouse Connect determina automáticamente el formato de escritura correcto para una columna a partir de su primer valor de datos no nulo. Por ejemplo, cuando el primer valor de una columna `DateTime` es un entero, el Client lo trata como un segundo desde la época.

Normalmente no es necesario aplicar una sobrescritura a un formato de escritura, pero los métodos de `clickhouse_connect.datatypes.format` pueden establecer uno de forma global. Las envolturas de contenedor, como `Array`, `Nullable` y `LowCardinality`, conservan el comportamiento de formato del tipo de elemento.

<div id="write-format-options">
  #### Opciones de formato de escritura
</div>

| Tipo de ClickHouse      | Tipo nativo de Python   | Formatos de escritura | Comentarios                                                                                                                                              |
| ----------------------- | ----------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 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            |                       | Una columna debe contener siempre texto o bytes de forma consistente.                                                                                    |
| FixedString             | bytes                   | string                | Los valores de cadena se rellenan con bytes cero. Los bytes vacíos se escriben como bytes completamente cero.                                            |
| Enum\[8,16]             | str or int              |                       | Inserte las etiquetas como cadenas o como sus valores enteros subyacentes.                                                                               |
| Date                    | datetime.date           | int                   | Los valores enteros se interpretan como días desde 1970-01-01.                                                                                           |
| Date32                  | datetime.date           | int                   | Los valores enteros se interpretan como desplazamientos de días con signo.                                                                               |
| DateTime                | datetime.datetime       | int                   | Los valores enteros se interpretan como segundos desde la época Unix.                                                                                    |
| DateTime64              | datetime.datetime       | int                   | Los valores enteros se interpretan como ticks con la precisión de la columna.                                                                            |
| Time                    | datetime.timedelta      | int, string, time     | Los valores enteros se interpretan como segundos.                                                                                                        |
| Time64                  | datetime.timedelta      | int, string, time     | Los valores enteros se interpretan como ticks con la precisión de la columna.                                                                            |
| IPv4                    | `ipaddress.IPv4Address` | string                | Se pueden insertar cadenas con el formato adecuado como direcciones IPv4                                                                                 |
| IPv6                    | `ipaddress.IPv6Address` | string                | Se pueden insertar cadenas con el formato adecuado como direcciones IPv6                                                                                 |
| Tuple                   | dict or tuple           |                       |                                                                                                                                                          |
| Map                     | dict                    |                       |                                                                                                                                                          |
| Nested                  | Sequence\[dict]         |                       |                                                                                                                                                          |
| UUID                    | uuid.UUID               | string                | Se pueden insertar cadenas con el formato adecuado como UUIDs de ClickHouse                                                                              |
| JSON                    | dict                    | string                | Se admiten diccionarios y cadenas con objetos JSON. El tipo heredado `Object('json')` no es compatible.                                                  |
| Variant                 | object                  |                       | Los valores usan la serialización nativa del miembro. Use `clickhouse_connect.datatypes.dynamic.typed_variant` cuando los tipos de Python sean ambiguos. |
| Dynamic                 | object                  |                       | Actualmente, los valores se insertan mediante su representación en String.                                                                               |
| QBit                    | Sequence\[float]        |                       | NumPy se usa automáticamente para una transposición de bits más rápida cuando está instalado.                                                            |

<div id="specialized-insert-methods">
  ### Métodos especializados de inserción
</div>

ClickHouse Connect proporciona métodos especializados de inserción para formatos de datos habituales:

* `insert_df` -- Inserta un DataFrame de Pandas como datos Native orientados a columnas. También admite nombres y tipos de columna explícitos o un `InsertContext` reutilizable.
* `insert_arrow` -- Inserta una tabla de PyArrow usando el formato de entrada Arrow de ClickHouse.
* `insert_df_arrow` -- Inserta un DataFrame de Pandas respaldado por Arrow o un DataFrame de Polars. Todas las columnas de Pandas deben usar `dtypes` basados en Arrow.

Los tres métodos aceptan `database`, `settings` y `transport_settings` HTTP por solicitud.

<Note>
  Una matriz de NumPy es una Sequence of Sequences válida y puede usarse como argumento `data` con el método principal `insert`, por lo que no se requiere un método especializado.
</Note>

<div id="pandas-dataframe-insert">
  #### Inserción con DataFrame de 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">
  #### Inserción de tablas de 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">
  #### Inserción de DataFrame respaldado por 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">
  ### Crear una tabla a partir de un esquema de PyArrow
</div>

`create_table_from_arrow_schema` genera una instrucción `CREATE TABLE` a partir de campos escalares comunes de Arrow. La correspondencia abarca enteros con y sin signo, valores de coma flotante, booleanos, cadenas, fechas y marcas de tiempo. Crea intencionadamente columnas de ClickHouse que no admiten NULL y genera `TypeError` para tipos de Arrow no compatibles, así que revise el DDL generado antes de ejecutarlo.

```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">
  ### Zonas horarias
</div>

Al insertar objetos `datetime` de Python en columnas `DateTime` o `DateTime64`, ClickHouse Connect los convierte en valores de época.

<div id="timezone-aware-datetime-objects">
  #### Objetos datetime con zona horaria
</div>

Los objetos con zona horaria conservan el instante representado. La zona horaria de origen no tiene que coincidir con la zona horaria declarada en la columna de 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 usa el módulo `zoneinfo` de la biblioteca estándar. El controlador ya no depende de `pytz`.
</Note>

<div id="timezone-naive-datetime-objects">
  #### Objetos datetime sin zona horaria
</div>

La configuración global `naive_datetime_insert` controla la inserción de objetos nativos de Python con valores `datetime` sin zona horaria. También se aplica a las cadenas ISO sin zona horaria aceptadas por las columnas `DateTime64`.

* `"local"` es el valor predeterminado en 1.x. Python interpreta el valor en la zona horaria del proceso al llamar a `.timestamp()`. Esto conserva el comportamiento existente.
* `"server"` interpreta el valor como hora local en la zona horaria declarada por la columna `DateTime` o `DateTime64`. Si la columna no tiene zona horaria, utiliza la zona horaria del servidor indicada cuando se conectó el Client.

Configure la opción antes de realizar una inserción. Se lee al serializar cada columna de inserción nativa que contiene objetos `datetime` de Python o cadenas ISO `DateTime64`, por lo que el cambio se aplica a los Clients existentes y a los contextos de inserción reutilizables.

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

Con `"server"`, ClickHouse Connect asigna el `tzinfo` de destino antes de convertir el valor a una época. Para las zonas horarias IANA, sigue las reglas de la biblioteca estándar para las transiciones de horario de verano. En una superposición de otoño se usa el valor `fold` de `datetime`. El valor predeterminado `fold=0` selecciona el desplazamiento anterior a la transición, mientras que `fold=1` selecciona el posterior. En un salto de primavera se usa la misma selección de desplazamiento, y no se rechaza ni se normaliza.

Las horas de reloj inexistentes durante un salto de primavera pueden no conservarse en un recorrido de ida y vuelta mediante un parámetro de consulta en modo de reloj, ya que el análisis de texto de ClickHouse puede seleccionar un desplazamiento diferente. Use un `datetime` con zona horaria o una hora de reloj válida cuando el instante sea importante.

La opción solo se aplica a inserciones nativas de objetos Python de valores `datetime` y cadenas ISO sin zona horaria aceptadas por `DateTime64`. Las columnas de NumPy y Pandas con dtype `datetime64` sin zona horaria conservan su conversión actual de hora de reloj UTC.

Para representar un instante específico independientemente de cualquiera de los modos, asigne la zona horaria deseada o proporcione explícitamente un entero de época.

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

Los parámetros de consulta `datetime` sin zona horaria usan la configuración independiente `naive_datetime_binding`. De forma predeterminada, el modo `"wall"` envía los campos de hora local sin conversión a la hora local del host. Consulte la sección [Argumento Parameters](/es/integrations/language-clients/python/driver-api#parameters-argument).

<div id="datetime-columns-with-timezone-metadata">
  #### Columnas DateTime con metadatos de zona horaria
</div>

Las columnas de ClickHouse pueden declarar metadatos de zona horaria, por ejemplo `DateTime('America/Denver')` o `DateTime64(3, 'Asia/Tokyo')`. Estos metadatos controlan cómo se presentan los valores al consultarlos.

Al insertar un valor con zona horaria, ClickHouse Connect conserva el instante representado. Para un valor sin zona horaria, la configuración `naive_datetime_insert` controla si se usa la zona horaria del proceso o la de la columna. Al consultar, el resultado usa la zona horaria de la columna, a menos que se proporcione una sobrescritura por columna con el argumento `column_tzs`. El argumento `query_tz` no sobrescribe la zona horaria declarada de la columna.

```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">
  ## Inserciones de archivos
</div>

`clickhouse_connect.driver.tools.insert_file` carga un archivo local en una tabla existente por streaming y delega el análisis en ClickHouse.

| Parámetro      | Tipo           | Predeterminado              | Descripción                                                                                                                                |
| -------------- | -------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `client`       | `Client`       | Obligatorio                 | Client síncrono utilizado para la inserción.                                                                                               |
| `table`        | str            | Obligatorio                 | Tabla de destino simple o calificada con la base de datos.                                                                                 |
| `file_path`    | str            | Obligatorio                 | Ruta local al archivo de entrada.                                                                                                          |
| `fmt`          | str            | `"CSV"` or `"CSVWithNames"` | Formato de entrada. El valor predeterminado es `"CSV"` cuando se proporciona `column_names` y `"CSVWithNames"` en caso contrario.          |
| `column_names` | Sequence\[str] | `None`                      | Columnas representadas por el archivo. No es obligatorio para los formatos que incluyen nombres.                                           |
| `database`     | str            | `None`                      | Base de datos de destino cuando la tabla no está calificada.                                                                               |
| `settings`     | dict           | `None`                      | Consulte [argumento Settings](/es/integrations/language-clients/python/driver-api#settings-argument-1).                                    |
| `compression`  | str            | `None`                      | Compresión existente del archivo, como `"zstd"`, `"lz4"` o `"gzip"`. `gzip` se infiere a partir de los nombres de archivo `.gz` y `.gzip`. |

La configuración del formato de entrada, como `input_format_allow_errors_ratio` y `input_format_allow_errors_num`, puede pasarse mediante `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,
    },
)
```

Para un `AsyncClient`, usa `await` con `insert_file_async` y los mismos argumentos:

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

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

La función auxiliar async lee el archivo en un hilo de trabajo antes de hacer `await` de `raw_insert`, por lo que el contenido del archivo se mantiene en memoria.
