Conectando Klaviyo y Snowflake

read
Last updated at:

Advanced Klaviyo Data Platform no está incluido en la aplicación de marketing estándar de Klaviyo, y se requiere una suscripción para acceder a la funcionalidad asociada. Visita nuestra guía de facturación para saber cómo contratar este plan.

Usamos el término "tabla" para los propósitos de este artículo; pero las vistas, vistas materializadas y tablas son todos objetos Snowflake válidos que se puede importar. Siempre y cuando Klaviyo pueda ejecutar SELECT col1 FROM table_name en el objeto, eres libre de usar lo que prefieras.

Las palabras clave "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY" y "OPTIONAL" en este documento deben interpretarse como se describe en RFC 2119.

Configuración del administrador de Snowflake

En esta sección se describen los pasos que debes seguir en tu entorno de Snowflake para permitir que Klaviyo importe tus datos.

  1. Genera una clave privada ejecutando el comando siguiente en tu terminal local:
    openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt
  2. Genera una clave pública que haga referencia a la clave privada ejecutando el comando siguiente en tu terminal:
    openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub
  3. Copia el archivo rsa_key.pub y pégalo en el script siguiente para reemplazar el valor del marcador de posición 'GENERATE_PUBLIC_KEY' de user_rsa_public_key. El script siguiente funcionará para los usuarios de Mac, o puedes abrir rsa_key.pub en un IDE y copiar el contenido completo del archivo si lo prefieres.
    # Mac terminal command to write the key to your terminal and copy it to the clipboard
    cat rsa_key.pub | tee /dev/tty | pbcopy
  4. Ejecuta el script siguiente en tu entorno de Snowflake en la creación de un usuario de servicio para que lo use Klaviyo. Debes tener privilegios de securityadmin y sysadmin para que puedas completar la configuración indicada abajo. A fin de revisar qué roles tienes, ejecuta SHOW GRANTS TO USER <your_username> y cerciórate de que tienes ambos roles en la lista. Ponte en contacto con un administrador de sistema si necesitas que ajusten tu rol.
    1. Siéntete en libertad de actualizar cualquiera de las variables establecidas al comienzo del script.
    2. En resumen:
      1. Elegirás un almacén existente o crearás uno nuevo
      2. Elegirás una base de datos existente o crearás una nueva para albergar los nuevos esquemas
      3. Crea dos esquemas nuevos KLAVIYO_TMP, y KLAVIYO_IMPORT_FROM_DWH
      4. Crearás una nueva política de red y lista de permisos de IP de Klaviyo
      5. Crearás un usuario y un rol para Klaviyo
    3. Este script es idempotente (se puede ejecutar con seguridad varias veces), pero no sobrescribirá los objetos existentes con nombres en conflicto.
BEGIN;

-- create variables for user / password / role / warehouse / database. 
-- Change these to whatever you prefer.
SET role_name = 'KLAVIYO_DATA_TRANSFER_ROLE'; -- all letters must be uppercase, ex. 'KLAVIYO_DATA_TRANSFER_ROLE'
SET user_name = 'KLAVIYO_DATA_TRANSFER_USER'; -- all letters must be uppercase, ex. 'KLAVIYO_DATA_TRANSFER_USER'
SET warehouse_name = 'KLAVIYO_DATA_TRANSFER_WAREHOUSE'; -- all letters must be uppercase, ex. 'KLAVIYO_DATA_TRANSFER_WAREHOUSE'
SET database_name = 'KLAVIYO_DATABASE'; -- all letters must be uppercase, ex. 'KLAVIYO_DATABASE'. If this database doesn't exist, a new one will be created.
SET network_policy = 'KLAVIYO_DATA_TRANSFER_NETWORK_POLICY'; -- all letters must be uppercase, ex. 'KLAVIYO_NETWORK_POLICY'
SET network_rule = 'KLAVIYO_DATA_TRANSFER_NETWORK_RULE'; -- all letters must be uppercase, ex. 'KLAVIYO_NETWORK_RULE'
/* replace GENERATE_PUBLIC_KEY below with generated public key */

-- DO NOT CHANGE
SET schema_name_tmp = $database_name || '.KLAVIYO_TMP';  -- DO NOT CHANGE
SET schema_name_import = $database_name || '.KLAVIYO_IMPORT_FROM_DWH';  -- DO NOT CHANGE
SET full_network_rule_tmp = $schema_name_tmp || '.' || $network_rule; -- DO NOT CHANGE
SET full_network_rule_import = $schema_name_import || '.' || $network_rule; -- DO NOT CHANGE


-- change role to sysadmin for warehouse / database steps
USE ROLE sysadmin;

-- create a warehouse for data transfer service
CREATE WAREHOUSE IF NOT EXISTS IDENTIFIER($warehouse_name)
    warehouse_size = xsmall
    warehouse_type = standard
    auto_suspend = 60
    auto_resume = true
    initially_suspended = true;

-- create database for data transfer service
CREATE DATABASE IF NOT EXISTS IDENTIFIER($database_name);

-- create schemas for data transfer service
CREATE SCHEMA IF NOT EXISTS IDENTIFIER($schema_name_tmp);
CREATE SCHEMA IF NOT EXISTS IDENTIFIER($schema_name_import);

-- change role to securityadmin for user / role steps
USE ROLE securityadmin;

-- create network rule and policy for database
GRANT USAGE ON DATABASE IDENTIFIER($database_name) TO ROLE securityadmin;
GRANT USAGE, CREATE NETWORK RULE ON SCHEMA IDENTIFIER($schema_name_tmp) TO ROLE securityadmin;
GRANT USAGE, CREATE NETWORK RULE ON SCHEMA IDENTIFIER($schema_name_import) TO ROLE securityadmin;

-- whitelist klaviyo ip ranges, for KLAVIYO_TMP schema 
CREATE NETWORK RULE IF NOT EXISTS IDENTIFIER($full_network_rule_tmp)
    type = IPV4
    value_list = (
        '184.72.183.187/32', '52.206.71.52/32', '3.227.146.32/32', '44.198.39.11/32', '35.172.58.121/32', '3.228.37.244/32', '54.88.219.8/32', '3.214.211.176/32'
        )
    comment = 'Klaviyo IP Ranges as of April 2025';
CREATE NETWORK POLICY IF NOT EXISTS IDENTIFIER($network_policy)
    allowed_network_rule_list = ($full_network_rule_tmp);

-- whitelist klaviyo ip ranges, for KLAVIYO_IMPORT_FROM_DWH schema 
CREATE NETWORK RULE IF NOT EXISTS IDENTIFIER($full_network_rule_import)
    type = IPV4
    value_list = (
        '184.72.183.187/32', '52.206.71.52/32', '3.227.146.32/32', '44.198.39.11/32', '35.172.58.121/32', '3.228.37.244/32', '54.88.219.8/32', '3.214.211.176/32'
        )
    comment = 'Klaviyo IP Ranges as of April 2025';
CREATE NETWORK POLICY IF NOT EXISTS IDENTIFIER($network_policy)
allowed_network_rule_list = ($full_network_rule_import);


-- create role for data transfer service
CREATE ROLE IF NOT EXISTS IDENTIFIER($role_name);
GRANT ROLE IDENTIFIER($role_name) TO ROLE sysadmin;

-- create a user for data transfer service
CREATE USER IF NOT EXISTS IDENTIFIER($user_name)
    type = SERVICE
    network_policy = $network_policy
    default_role = $role_name
    default_warehouse = $warehouse_name
    rsa_public_key = 'GENERATE_PUBLIC_KEY';
GRANT ROLE IDENTIFIER($role_name) TO USER IDENTIFIER($user_name);
ALTER USER IDENTIFIER($user_name) SET NETWORK_POLICY = $network_policy;

-- grant service role access to warehouse
GRANT USAGE
    ON WAREHOUSE IDENTIFIER($warehouse_name)
    TO ROLE IDENTIFIER($role_name);

-- grant service access to database
GRANT MONITOR, USAGE
    ON DATABASE IDENTIFIER($database_name)
    TO ROLE IDENTIFIER($role_name);

-- Grant privileges for KLAVIYO_TMP 
GRANT USAGE ON SCHEMA IDENTIFIER($schema_name_tmp) TO ROLE IDENTIFIER($role_name);
GRANT MONITOR, USAGE, CREATE TABLE, CREATE VIEW, CREATE SEQUENCE, CREATE FUNCTION, CREATE PROCEDURE
    ON SCHEMA IDENTIFIER($schema_name_tmp)
    TO ROLE IDENTIFIER($role_name);
GRANT ALL ON FUTURE TABLES IN SCHEMA IDENTIFIER($schema_name_tmp) TO ROLE IDENTIFIER($role_name);

-- Grant privileges for KLAVIYO_IMPORT_FROM_DWH
GRANT USAGE ON SCHEMA IDENTIFIER($schema_name_import) TO ROLE IDENTIFIER($role_name);
GRANT SELECT
    ON FUTURE TABLES
    IN SCHEMA IDENTIFIER($schema_name_import)
    TO ROLE IDENTIFIER($role_name);

COMMIT;

Configuración de datos de Snowflake

Arriba, creaste dos nuevos esquemas.

  • KLAVIYO_TMP será usado exclusivamente por Klaviyo. NO DEBES modificar ninguna tabla creada en este esquema. Klaviyo eliminará estas tablas cuando ya no sean necesarias.
  • KLAVIYO_IMPORT_FROM_DWH es donde debes guardar tus tablas finales para que Klaviyo las importe. Cuando realices el proceso de crear la sincronización, aparecerán todas las tablas de este esquema para que puedas elegir entre ellas. Por lo tanto, solo DEBES guardar las tablas finales que deseas importar para evitar confusiones durante la configuración.

Todas las tablas que planeas importar a Klaviyo deben cumplir con los siguientes criterios.

Requisitos de marca de tiempo

  1. Las tablas DEBEN contener un campo de marca de tiempo que indique cuándo se creó o actualizó la fila. Será frecuentemente insert_at o updated_at. Lo establecerás para cada tabla durante el proceso de crear la sincronización.
    1. El campo de marca de tiempo DEBE ser monotónicamente creciente (es decir, siempre debe aumentar o mantenerse igual, y nunca disminuir).
    2. Después de creada la sincronización, NO DEBES establecer el valor de la marca de tiempo de una fila en el pasado, o Klaviyo podría no seleccionar dicha fila.
    3. La zona horaria de este campo en particular no es importante para Klaviyo, siempre que sigas los requisitos indicados arriba
    4. Tus marcas de tiempo DEBEN estar en UTC o incluir información sobre la zona horaria. Si falta información sobre la zona horaria, Klaviyo supondrá que es UTC. En el caso de propiedades personalizadas, estas marcas de tiempo permanecen en formato de cadena, lo que te permite interpretarlas en tu zona horaria preferida.
  2. El campo de marca de tiempo DEBE reflejar cuándo se insertó la fila y debe agruparse cerca de la fecha actual. Klaviyo sincroniza tus datos escaneando periodos de 1 hora a partir del valor de la marca de tiempo más antiguo de tu tabla. Una sola fila con una marca de tiempo en el pasado (por ejemplo, un registro de 2023 en el que todas las demás son recientes) hace que Klaviyo recorra cada periodo de 1 hora a partir de esa fecha en cada ciclo de sincronización. Esta es una limitación actual que debe resolverse en una próxima versión.
  3. Considera la densidad de filas por periodo de 1 hora. Dado que los datos se cargan en lotes de periodos de marca de tiempo de 1 hora, millones de registros en el mismo periodo de 1 hora pueden dar lugar a sincronizaciones lentas o estancadas. Mientras que el límite superior de la densidad de filas depende de la cantidad de datos en cada fila, una buena regla general a tener en cuenta es 100.000 filas por periodo de marca de tiempo de 1 hora.
  4. Klaviyo te recomienda que establezcas el campo de marca de tiempo con CURRENT_TIMESTAMP() o una función equivalente cada vez que añadas filas a la tabla desde la que se sincronizará. Varias filas pueden tener la misma marca de tiempo. Puedes ver el ejemplo siguiente.
INSERT INTO table_name AS 

SELECT ... 

    , CURRENT_TIMESTAMP() AS inserted_at

... 

Estructura de la tabla

  1. Las tablas se DEBEN tratar como "solo añadir" (también conocidas como "sólo insertar")
    1. Si en vez de ello prefieres actualizar las filas en su lugar, DEBES actualizar el campo de marca de tiempo, para que Klaviyo pueda identificar el cambio.
  2. Las tablas DEBEN estar ordenadas con base en tu columna de marca de tiempo. Snowflake se encargará de su agrupamiento y partición con base en tu orden de inserción. Esto ayudará a optimizar las consultas de importación de Klaviyo, manteniendo bajos los costos de computación en Snowflake

Singularidad y uniformidad del perfil

  1. DEBES cerciorarte de que cada propiedad del perfil se importe de una sola fuente de datos (tabla). Klaviyo impide seleccionar la misma propiedad de diferentes tablas durante la creación de la sincronización, simplificando este requisito.
  2. DEBES usar los mismos identificadores de perfil (correo electrónico, número de teléfono, ID externa, etc.) en todas tus tablas de importación, para minimizar el riesgo de que se creen perfiles duplicados.
    1. Klaviyo creará un nuevo perfil si el identificador de perfil que proporcionas no coincide con un perfil ya existente en Klaviyo.
    2. Ejemplo: Table1 (Email, fav_color) + Table2 (Teléfono, cumpleaños)
      1. Esto podría crear 2 perfiles para la misma persona si el perfil no existe actualmente. Si existe un perfil, Klaviyo gestionará internamente la resolución del perfil y las actualizaciones. 
    3. Una forma de evitar este problema es utilizar una sola tabla de importación para todos tus perfiles.

Prevención del bucle circular de importación-exportación

  1. DEBES gestionar cuidadosamente las situaciones en las que se usan las funciones de importación y exportación, para evitar bucles circulares de importación-exportación. Cerciórate de que tu proceso de exportación no retroalimente datos a una tabla de un paso previo a tu tabla de importación, ya que Klaviyo no detecta actualmente tal situación.
    1. Klaviyo todavía no cuenta con la lógica para detectar dicha situación.
    2. Esto sería algo así como:
      1. En cada ciclo de sincronización de exportación, Klaviyo exportará todos tus perfiles
      2. Luego, agregas todos los perfiles exportados a tu tabla de importación mediante una serie de transformaciones.
      3. En cada ciclo de sincronización de importación, Klaviyo leerá todos los perfiles de tu tabla de importación, que en última instancia se reexportarán
    3. Situaciones en las que probablemente sea seguro
      1. Si sólo usas la tabla de exportación para restringir las filas agregadas a tu tabla de importación
      2. Si verificas que la tabla de exportación no añade filas a tu tabla de importación.
    4. ¿Cuáles son las consecuencias de un bucle circular de importación-exportación?
      1. Esto causará costos de computación innecesarios para ti y para Klaviyo.

Guía de solución de problemas

La sincronización parece atascada

Si la sincronización se está ejecutando, pero tus datos no aparecen en Klaviyo después de varias horas, o la sincronización tarda un tiempo inusualmente largo en completarse, un valor de marca de tiempo en el pasado es la causa más probable:

  • Revisa tu tabla para ver si hay filas con una marca de tiempo significativamente más antigua que el resto de tus datos (por ejemplo, una fila de 2023, cuando todas las demás son de la semana pasada). Incluso una sola fila atípica obliga a Klaviyo a iterar a través de miles de periodos vacíos de 1 hora antes de llegar a los datos recientes.
  • Corrección: Actualiza o elimina las filas con marcas de tiempo del pasado, o configúralas en un valor reciente, antes de habilitar o volver a habilitar la sincronización. Para los rellenos, configura todas las filas históricas con la misma marca de tiempo reciente (por ejemplo, el tiempo de ejecución del trabajo actual) para minimizar el número de periodos de 1 hora que Klaviyo debe escanear. Si hay más de ~100 000 filas, establece sus marcas de tiempo en lotes de ~100 000 cada (al menos) 61 minutos.

Se recomienda la configuración de la clave de agrupamiento de Snowflake

Agrupar tu tabla de Snowflake en la columna de marca de tiempo permite que las consultas de importación de Klaviyo omitan las microparticiones innecesarias, lo que reduce el tiempo de sincronización y los costos de computación de Snowflake:

ALTER TABLE your_database.KLAVIYO_IMPORT_FROM_DWH.your_table CLUSTER BY (your_timestamp_column);

x
¿Fue útil este artículo?
Usuarios a los que les pareció útil: 0 de 0