> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-fix-nav-issues.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Migración de Snowflake a ClickHouse

# Migración de Snowflake a ClickHouse

export const Image = ({img, alt, size}) => {
  return <Frame>
      <img src={img} alt={alt} />
    </Frame>;
};

> Esta guía le muestra cómo migrar datos de Snowflake a ClickHouse.

La migración de datos entre Snowflake y ClickHouse requiere el uso de un almacenamiento de objetos,
como S3, como ubicación intermedia para la transferencia. El proceso de migración también
se basa en el uso de los comandos `COPY INTO` de Snowflake y `INSERT INTO SELECT`
de ClickHouse.

<Steps>
  <Step>
    ## Exportar datos desde Snowflake

    <Image img="https://mintcdn.com/private-7c7dfe99-fix-nav-issues/0xkAyEEn8ANRFZGQ/images/migrations/migrate_snowflake_clickhouse.png?fit=max&auto=format&n=0xkAyEEn8ANRFZGQ&q=85&s=67ea30f563fb27e4a00689b8f6804979" size="md" alt="Migración de Snowflake a ClickHouse" width="1600" height="1106" data-path="images/migrations/migrate_snowflake_clickhouse.png" />

    Exportar datos desde Snowflake requiere usar un stage externo, como se muestra en el diagrama anterior.

    Supongamos que queremos exportar una tabla de Snowflake con el siguiente esquema:

    ```sql theme={null}
    CREATE TABLE MYDATASET (
       timestamp TIMESTAMP,
       some_text varchar,
       some_file OBJECT,
       complex_data VARIANT,
    ) DATA_RETENTION_TIME_IN_DAYS = 0;
    ```

    Para mover los datos de esta tabla a una base de datos de ClickHouse, primero debemos copiarlos a un stage externo. Al copiar datos, recomendamos usar Parquet como formato intermedio, ya que permite conservar la información de tipos, preserva la precisión, comprime bien y admite de forma nativa estructuras anidadas habituales en analítica.

    En el ejemplo siguiente, creamos en Snowflake un formato de archivo con nombre para representar Parquet y las opciones de archivo deseadas. Después, especificamos qué bucket contendrá nuestro dataset copiado. Por último, copiamos el dataset al bucket.

    ```sql theme={null}
    CREATE FILE FORMAT my_parquet_format TYPE = parquet;

    -- Crear el stage externo que especifica el bucket de S3 al que se copiarán los datos
    CREATE OR REPLACE STAGE external_stage
    URL='s3://mybucket/mydataset'
    CREDENTIALS=(AWS_KEY_ID='<key>' AWS_SECRET_KEY='<secret>')
    FILE_FORMAT = my_parquet_format;

    -- Aplicar el prefijo "mydataset" a todos los archivos y especificar un tamaño máximo de archivo de 150mb
    -- El parámetro `header=true` es obligatorio para obtener los nombres de las columnas
    COPY INTO @external_stage/mydataset from mydataset max_file_size=157286400 header=true;
    ```

    Para un dataset de alrededor de 5 TB, con un tamaño máximo de archivo de 150 MB, y usando un warehouse 2X-Large de Snowflake ubicado en la misma región de AWS `us-east-1`, copiar los datos al bucket de S3 llevará unos 30 minutos.
  </Step>

  <Step>
    ## Importar en ClickHouse

    Una vez que los datos están almacenados en un almacenamiento de objetos intermedio, se pueden usar funciones de ClickHouse como la [función de tabla s3](/es/reference/functions/table-functions/s3) para insertarlos en una tabla, como se muestra a continuación.

    Este ejemplo usa la [función de tabla s3](/es/reference/functions/table-functions/s3) para AWS S3, pero la [función de tabla gcs](/es/reference/functions/table-functions/gcs) puede usarse para Google Cloud Storage y la [función de tabla azureBlobStorage](/es/reference/functions/table-functions/azureBlobStorage) para Azure Blob Storage.

    Suponiendo el siguiente esquema de la tabla de destino:

    ```sql theme={null}
    CREATE TABLE default.mydataset
    (
      `timestamp` DateTime64(6),
      `some_text` String,
      `some_file` Tuple(filename String, version String),
      `complex_data` Tuple(name String, description String),
    )
    ENGINE = MergeTree
    ORDER BY (timestamp)
    ```

    A continuación, podemos usar el comando `INSERT INTO SELECT` para insertar los datos desde S3 en una tabla de ClickHouse:

    ```sql theme={null}
    INSERT INTO mydataset
    SELECT
      timestamp,
      some_text,
      JSONExtract(
        ifNull(some_file, '{}'),
        'Tuple(filename String, version String)'
      ) AS some_file,
      JSONExtract(
        ifNull(complex_data, '{}'),
        'Tuple(filename String, description String)'
      ) AS complex_data,
    FROM s3('https://mybucket.s3.amazonaws.com/mydataset/mydataset*.parquet')
    SETTINGS input_format_null_as_default = 1, -- Garantiza que las columnas se inserten con el valor predeterminado si los valores son NULL
    input_format_parquet_case_insensitive_column_matching = 1 -- La coincidencia entre las columnas de los datos de origen y la tabla de destino no debe distinguir entre mayúsculas y minúsculas
    ```

    <Info>
      **Nota sobre las estructuras de columnas anidadas**

      Las columnas `VARIANT` y `OBJECT` del esquema original de la tabla de Snowflake se generarán como cadenas JSON de forma predeterminada, lo que nos obliga a convertirlas al insertarlas en ClickHouse.

      Snowflake convierte estructuras anidadas como `some_file` en cadenas JSON al copiarlas. Para importar estos datos, debemos transformar esas estructuras en Tuples en el momento de la inserción en ClickHouse, usando la [función JSONExtract](/es/reference/functions/regular-functions/json-functions#JSONExtract), como se muestra arriba.
    </Info>
  </Step>

  <Step>
    ## Verificar que la exportación de datos se haya realizado correctamente

    Para comprobar si los datos se insertaron correctamente, simplemente ejecuta una consulta `SELECT` sobre tu nueva tabla:

    ```sql theme={null}
    SELECT * FROM mydataset LIMIT 10;
    ```
  </Step>
</Steps>
