Connecter Klaviyo et Snowflake
Advanced Klaviyo Data Platform n’est pas inclus dans l’application marketing standard de Klaviyo, et un abonnement est nécessaire pour accéder aux fonctionnalités associées. Consultez notre guide de facturation pour savoir comment acheter cet abonnement.
Aux fins de cet article, nous utilisons le terme « tableau », mais les vues, les vues matérialisées et les tableaux sont tous des objets Snowflake valides qui peuvent être importés. Tant que Klaviyo peut exécuter SELECT col1 FROM table_name sur l'objet, vous pouvez utiliser ce que vous préférez.
Les mots-clés « DOIT », « NE DOIT PAS », « REQUIS », « DOIT », « NE DOIT PAS », « DEVRAIT », « NE DEVRAIT PAS », « RECOMMANDÉ », « PEUT » et « FACULTATIF » dans ce document doivent être interprétés comme décrit dans RFC 2119.
Configuration de l’Administrateur Snowflake
Cette section décrit les étapes que vous devez suivre dans votre environnement Snowflake pour permettre à Klaviyo d’importer vos données.
- Générez une clé privée en exécutant la commande suivante dans votre terminal local :
openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt - Générez une clé publique qui fait référence à la clé privée en exécutant la commande suivante dans votre terminal :
openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub - Copiez le fichier rsa_key.pub et collez-le dans le script ci-dessous pour remplacer la valeur de remplissage « GENERATE_PUBLIC_KEY » pour user_rsa_public_key. Le script ci-dessous fonctionnera pour les utilisateurs de Mac, ou vous pouvez ouvrir rsa_key.pub dans un IDE et copier le contenu complet du fichier si vous préférez.
# Mac terminal command to write the key to your terminal and copy it to the clipboard
cat rsa_key.pub | tee /dev/tty | pbcopy - Exécutez le script suivant dans votre environnement Snowflake pour créer un utilisateur de service que Klaviyo pourra utiliser. Vous devez disposer des droits securityadmin et sysadmin pour effectuer la configuration ci-dessous. Pour vérifier quels sont les rôles dont vous disposez, exécutez SHOW GRANTS TO USER <your_username> <votre_nom_d’utilisateur> et assurez-vous que les deux rôles sont indiqués. Contactez un administrateur système si vous avez besoin de modifier votre rôle.
- N’hésitez pas à mettre à jour l’une des variables définies au début du script.
- En résumé, vous allez :
- Choisissez un entrepôt existant ou créez-en un nouveau
- Choisissez une base de données existante ou créez-en une nouvelle pour contenir les nouveaux schémas
- Créez deux nouveaux schémas
KLAVIYO_TMP, etKLAVIYO_IMPORT_FROM_DWH - Créez une nouvelle politique réseau et autorisez les adresses IP Klaviyo
- Créer un utilisateur et un rôle pour Klaviyo
- Ce script est impuissant (peut être exécuté plusieurs fois en toute sécurité), mais il ne remplacera pas les objets existants dont les noms sont contradictoires.
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; Configuration des données Snowflake
Ci-dessus, vous avez créé deux nouveaux schémas.
- KLAVIYO_TMP sera utilisé exclusivement par Klaviyo. Vous NE DEVEZ PAS modifier les tables créées dans ce schéma. Klaviyo supprimera ces tableaux lorsqu’ils ne seront plus nécessaires.
- Klaviyo_IMPORT_FROM_DWH est l’endroit où vous devez stocker vos tableaux finaux pour que Klaviyo les importe. Lorsque vous passez par le processus de création de la synchronisation, toutes les tables de ce schéma sont répertoriées. Par conséquent, vous NE DEVEZ stocker que les tableaux finaux que vous souhaitez importer afin d’éviter toute confusion lors de la configuration.
Toutes les tables que vous prévoyez d’importer dans Klaviyo doivent répondre aux critères suivants.
Exigences en matière d’horodatage
- Les tableaux DOIVENT contenir un champ d’horodatage qui indique quand la ligne a été créée ou mise à jour. Souvent, il sera inséré_à ou mis à jour_à. Vous le définirez pour chaque tableau au cours du processus de création de la synchronisation.
- Le champ d’horodatage DOIT être en augmentation monotone (c’est-à-dire qu’il doit toujours être plus grand ou rester le même, sans jamais être plus petit).
- Après la création de la synchronisation, vous NE DEVEZ PAS définir la valeur de l’horodatage d’une ligne sur une période antérieure, sinon Klaviyo ne pourra pas récupérer cette ligne.
- Le fuseau horaire de ce champ particulier n’est pas important pour Klaviyo, à condition que vous respectiez les exigences ci-dessus
- Vos horodatages DOIVENT être en UTC ou inclure des informations sur le fuseau horaire. Si les informations relatives au fuseau horaire sont manquantes, Klaviyo prendra les valeurs UTC. Pour les propriétés personnalisées, ces horodatages restent au format chaîne, ce qui vous permet de les interpréter dans le fuseau horaire de votre choix.
- Le champ d’horodatage DOIT refléter la date d’insertion de la ligne et doit être regroupé à proximité de la date du jour. Klaviyo synchronise les données en analysant des fenêtres d’une heure à partir de la valeur d’horodatage la plus ancienne de votre tableau. Une seule ligne avec un horodatage très ancien (par exemple, un enregistrement de 2023 lorsque tous les autres sont récents) fait que Klaviyo itère toutes les fenêtres d’une heure à partir de cette date, à chaque cycle de synchronisation. Il s’agit d’une limitation actuelle qui devrait être résolue dans une version à venir.
- Tenez compte de la densité de lignes par fenêtre d’horodatage de 1 heure. Étant donné que les données sont chargées par lots de fenêtres d’horodatage d’une heure, des millions d’enregistrements dans la même fenêtre d’une heure peuvent entraîner des synchronisations lentes ou bloquées. Alors que la limite supérieure de la densité des lignes dépend de la quantité de données de chaque ligne, une bonne règle empirique à garder à l’esprit est de 100 000 lignes par fenêtre d’horodatage de 1 heure.
- Klaviyo vous recommande de définir le champ d’horodatage avec CURRENT_TIMESTAMP() ou une fonction équivalente chaque fois que vous ajoutez des lignes au tableau à partir duquel nous allons effectuer la synchronisation. Plusieurs lignes peuvent avoir le même horodatage. Consultez l’exemple ci-dessous.
INSERT INTO table_name AS
SELECT ...
, CURRENT_TIMESTAMP() AS inserted_at
... Structure du tableau
- Les tableaux DOIVENT être traités comme des ajouts uniquement (c’est-à-dire des insertions uniquement).
- Si vous préférez mettre à jour les lignes en place, vous DEVEZ mettre à jour le champ d’horodatage afin que Klaviyo puisse identifier le changement.
- Les tableaux DOIVENT être classés dans votre colonne d’horodatage. Snowflake gérera le clustering et le partitionnement en fonction de votre ordre d’insertion. Cela vous aidera à optimiser les requêtes d’importation de Klaviyo, tout en réduisant les coûts de calcul dans Snowflake
Uniquité et cohérence du profil
- Vous DEVEZ vous assurer que chaque propriété de profil est importée à partir d’une seule source de données (tableau). Klaviyo empêche de sélectionner la même propriété dans différents tableaux lors de la création de la synchronisation, ce qui simplifie cette exigence.
- Vous DEVEZ utiliser le ou les mêmes identifiants de profil (e-mail, numéro de téléphone, identifiant externe, etc.) dans tous vos tableaux d’importation, afin de minimiser le risque de création de profils en double.
- Klaviyo créera de nouveaux profils si l’identifiant de profil que vous fournissez ne correspond pas à un profil existant dans Klaviyo.
- Exemple : Tableau 1 (Email, fav_color) + Tableau 2 (Téléphone, anniversaire)
- Cela pourrait créer deux profils pour la même personne si le profil n’existe pas actuellement. S’il existe un profil, Klaviyo s’en charge en interne.
- Une façon d’éviter ce problème est de n’utiliser qu’un seul tableau d’importation pour tous vos profils.
Prévention de la boucle d’importation-exportation circulaire
- Vous DEVEZ gérer avec soin les scénarios dans lesquels les fonctionnalités d’importation et d’exportation sont utilisées pour éviter des boucles d’importation-exportation circulaires. Veillez à ce que votre processus d’exportation ne renvoie pas les données dans un tableau situé en amont de votre tableau d’importation, car Klaviyo ne détecte pas ce scénario actuellement.
- Klaviyo n’a pas encore de logique pour détecter ce scénario.
- Cela ressemblerait à ceci :
- À chaque cycle de synchronisation d’exportation, Klaviyo exportera tous vos profils
- Ensuite, vous ajoutez tous vos profils exportés à votre tableau d’importation par le biais d’une série de transformations.
- À chaque cycle de synchronisation d’importation, Klaviyo lit tous les profils de votre tableau d’importation, qui sont réexportés
- Scénarios où cela est probablement sûr
- si vous utilisez uniquement le tableau d’exportation pour restreindre les lignes ajoutées à votre tableau d’importation
- Si vous vérifiez que le tableau d’exportation n’ajoute pas de lignes à votre tableau d’importation.
- Quelles sont les conséquences d'une boucle d'import-export circulaire ?
- Cela entraînera des coûts de calcul inutiles pour vous et Klaviyo.
Résolution de problèmes
La synchronisation semble bloquée.
Si votre synchronisation est en cours, mais que les données n’apparaissent pas dans Klaviyo après plusieurs heures, ou si la synchronisation prend un temps inhabituellement long, une valeur d’horodatage datant de loin est la cause la plus probable :
- Recherchez dans votre tableau les lignes dont l’horodatage est nettement plus ancien que le reste de vos données (par exemple, une ligne de 2023, alors que toutes les autres datent de la semaine dernière). Même une seule ligne aberrante force Klaviyo à itérer à travers des milliers de fenêtres vides d’une heure avant d’atteindre les données récentes.
- Correction : mettez à jour ou supprimez toutes les lignes dont l’horodatage remonte loin dans le passé, ou définissez-les sur une valeur récente, avant d’activer ou de réactiver la synchronisation. Pour les saisies inversées, définissez toutes les lignes historiques sur le même horodatage récent (par exemple, le temps d’exécution de la tâche en cours) afin de réduire le nombre de fenêtres d’une heure que Klaviyo doit analyser. Si plus de 100 000 lignes, définissez leurs horodatages par lots d’environ 100 000 toutes les (au moins) 61 minutes d’intervalle.
Configuration recommandée de la clé de clustering Snowflake
Le regroupement de votre tableau Snowflake dans la colonne d’horodatage permet à Klaviyo d’ignorer les micro-partitions inutiles, ce qui réduit le temps de synchronisation et les coûts de calcul de Snowflake :
ALTER TABLE your_database.KLAVIYO_IMPORT_FROM_DWH.your_table CLUSTER BY (your_timestamp_column);