Conexión de Klaviyo y Snowflake
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 las funciones asociadas. Consulta nuestra guía de facturación para saber cómo adquirir este plan.
A los efectos de este artículo, utilizamos el término «tabla», pero las vistas, las vistas materializadas y las tablas son objetos de Snowflake válidos que se pueden 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» de este documento deben interpretarse tal y como se describe en RFC 2119.
Configuración de Snowflake Administrador
En esta sección se describen los pasos que debes seguir en tu entorno de Snowflake para permitir que Klaviyo importe tus datos.
- Genera una clave privada ejecutando el siguiente comando en tu terminal local:
openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt - Genera una clave pública que haga referencia a la clave privada ejecutando el siguiente comando en tu terminal:
openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub - Copia el archivo rsa_key.pub y pégalo en el script a continuación para sustituir el valor de marcador de posición «GENERATE_PUBLIC_KEY» para user_rsa_public_key. El siguiente script funcionará para 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 - Ejecuta el siguiente script en tu entorno de Snowflake para crear un usuario de servicio para que lo use Klaviyo. Debes tener privilegios de administrador de seguridad y administrador del sistema para completar la configuración a continuación. Para revisar qué rol(s) tienes, ejecuta SHOW GRANTS TO USER <your_username> y asegúrate de que tengas ambos roles en la lista. Ponte en contacto con un administrador del sistema si necesitas ajustar tu rol.
- No dudes en actualizar cualquiera de las variables establecidas al principio del script.
- En resumen, tú:
- Elige un almacén existente o crea uno nuevo
- Elige una base de datos existente o crea una nueva para mantener los nuevos esquemas
- Crear dos nuevos esquemas
KLAVIYO_TMP, yKLAVIYO_IMPORT_FROM_DWH - Crea una nueva política de red y permite la lista de direcciones IP de Klaviyo
- Crear un usuario y un rol para Klaviyo
- Este script es idempotente (se puede ejecutar de forma segura 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á utilizado 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 deberías almacenar tus tablas finales para que Klaviyo las importe. Cuando vayas a través del proceso de creación de sincronización, todas las tablas de este esquema se mostrarán para que elijas. Por lo tanto, DEBES almacenar solo las tablas finales que quieras importar para evitar confusiones durante la configuración.
Todas las tablas que quieras importar a Klaviyo deben cumplir los siguientes criterios.
Requisitos de marca de tiempo
- Las tablas DEBEN contener un campo de marca de tiempo que indique cuándo se creó o actualizó la fila. A menudo, esto se insertará en o actualizará en. Lo establecerás para cada tabla durante el proceso de creación de la sincronización.
- El campo de marca de tiempo DEBE estar aumentando monótonamente (es decir, debe ser siempre cada vez más grande o mantenerse igual, nunca cada vez más pequeño).
- Después de crear la sincronización, NO DEBES establecer el valor de la marca de tiempo de una fila como una hora del pasado o Klaviyo puede no recoger esa fila.
- La zona horaria de este campo en particular no es importante para Klaviyo, siempre que sigas los requisitos anteriores
- 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 asumirá el UTC. Para las propiedades personalizadas, estas marcas de tiempo permanecen en formato de cadena, lo que te permite interpretarlas en tu zona horaria preferida.
- El campo de marca de tiempo DEBE reflejar cuándo se insertó la fila y debe agruparse cerca de la fecha actual. Klaviyo sincroniza los datos analizando periodos de 1 hora a partir del valor de marca de tiempo más antiguo de la tabla. Una sola fila con una marca de tiempo muy antigua (por ejemplo, un registro de 2023 en el que todos los demás son recientes) hace que Klaviyo altere cada ventana de 1 hora a partir de esa fecha en cada ciclo de sincronización. Se trata de una limitación actual que debería resolverse en una próxima versión.
- Ten en cuenta la densidad de filas por periodo de marca de tiempo 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. Si bien el límite superior de 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 cada ventana de marca de tiempo de 1 hora.
- 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 sincronizaremos. Varias filas pueden tener la misma marca de tiempo. Puedes ver el ejemplo a continuación.
INSERT INTO table_name AS
SELECT ...
, CURRENT_TIMESTAMP() AS inserted_at
... Estructura de la tabla
- Las tablas DEBEN tratarse como solo anexos (es decir, solo inserciones).
- Si prefieres actualizar las filas en su lugar, DEBES actualizar el campo de marca de tiempo para que Klaviyo pueda identificar el cambio.
- Las tablas DEBEN ser ordenadas en tu columna de marca de tiempo. Snowflake se encargará de agrupar y dividir en función de tus pedidos de insertos. Esto ayudará a optimizar las consultas de importación de Klaviyo y a reducir los costes informáticos en Snowflake.
Unicidad y coherencia del perfil
- DEBES asegurarte de que cada propiedad de perfil se importe de un solo origen de datos (tabla). Klaviyo impide seleccionar la misma propiedad de diferentes tablas durante la creación de la sincronización, lo que simplifica este requisito.
- DEBES usar los mismos identificadores de perfil (correo electrónico, número de teléfono, ID externo, etc.) en todas tus tablas de importación, para minimizar el riesgo de que se creen perfiles duplicados.
- Klaviyo creará nuevos perfiles si el identificador de perfil que proporciones no coincide con un perfil existente en Klaviyo.
- Ejemplo: Table1 (correo electrónico, fav_color) + Table2 (teléfono, cumpleaños)
- Esto podría crear 2 perfiles para la misma persona si el perfil no existe actualmente. Si existe un perfil, Klaviyo se encargará de la resolución del perfil y de las actualizaciones internamente.
- Una forma de evitar este problema es utilizar solo una tabla de importación para todos tus perfiles.
Prevención de Loop de Importación-Exportación Circular
- Debes gestionar cuidadosamente los escenarios en los que se utilizan tanto las funciones de importación como las de exportación para evitar los bucles circulares de importación-exportación. Asegúrate de que tu proceso de exportación no retroalimente los datos a una tabla que esté por encima de la tabla de importación, ya que Klaviyo no detecta este escenario en estos momentos.
- Klaviyo aún no tiene lógica para detectar este escenario.
- Esto sería algo así como:
- En cada ciclo de sincronización de exportación, Klaviyo exportará todos tus perfiles
- Luego, añades todos tus perfiles exportados a tu tabla de importación a través de una serie de transformaciones.
- En cada ciclo de sincronización de importaciones, Klaviyo leerá todos los perfiles de tu tabla de importación, que eventualmente se volverán a exportar
- Escenarios en los que probablemente sea seguro
- Si solo utilizas la tabla de exportación para restringir las filas añadidas a tu tabla de importación
- Si verificas que la tabla de exportación no añada filas a tu tabla de importación.
- ¿Cuáles son las consecuencias de un bucle circular de importación-exportación?
- Esto te supondrá costes informáticos innecesarios tanto para ti como para Klaviyo.
Solución de problemas
La sincronización parece atascada
Si la sincronización se está ejecutando, pero los datos no aparecen en Klaviyo después de varias horas, o si 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:
- Comprueba en tu tabla las 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 última semana). Incluso una sola fila de valores atípicos obliga a Klaviyo a iterar a través de miles de ventanas vacías de 1 hora antes de llegar a los datos recientes.
- Corrección: actualiza o elimina las filas con marcas de tiempo muy antiguas, o bien configúralas en un valor reciente, antes de habilitar o volver a habilitar la sincronización. En el caso de los rellenos, establece todas las filas históricas en 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 analizar. Si hay más de ~100 000 filas, establece sus marcas de tiempo en lotes de ~100 000 cada (al menos) 61 minutos.
Configuración de clave de agrupación recomendada 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 tanto el tiempo de sincronización como tus costos de computación de Snowflake:
ALTER TABLE your_database.KLAVIYO_IMPORT_FROM_DWH.your_table CLUSTER BY (your_timestamp_column);