Collegamento tra Klaviyo e Snowflake
Advanced Klaviyo Data Platform non è incluso nell'applicazione di marketing standard di Klaviyo e per accedere alle funzionalità associate è necessario un abbonamento. Visita la nostra guida alla fatturazione per scoprire come acquistare questo piano.
Ai fini di questo articolo utilizziamo il termine "tabella", ma le viste, le viste materializzate e le tabelle sono tutti oggetti Snowflake validi che possono essere importati. Fintanto che Klaviyo può eseguire SELECT col1 FROM table_name sull'oggetto, puoi utilizzare quello che preferisci.
Le parole chiave "DEVI", "NON DEVI", "OBBLIGATORIO", "DEVE", "NON DEVE", "DOVRESTI", "NON DOVRESTI", "CONSIGLIATO", "PUOI" e "FACOLTATIVO" in questo documento devono essere interpretate come descritto in RFC 2119.
Configurazione di Snowflake Amministratore
Questa sezione illustra i passaggi da seguire nel tuo ambiente Snowflake per consentire a Klaviyo di importare i tuoi dati.
- Genera una chiave privata eseguendo il seguente comando nel tuo terminale locale:
openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt - Genera una chiave pubblica che faccia riferimento alla chiave privata eseguendo il seguente comando nel tuo terminale:
openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub - Copiare rsa_key.pub e incollarlo nello script sottostante per sostituire il valore segnaposto "GENERATE_PUBLIC_KEY" per user_rsa_public_key. Lo script qui sotto funziona per gli utenti Mac, oppure puoi aprire rsa_key.pub in un IDE e copiare l'intero contenuto del file, se preferisci.
# Mac terminal command to write the key to your terminal and copy it to the clipboard
cat rsa_key.pub | tee /dev/tty | pbcopy - Esegui il seguente script nel tuo ambiente Snowflake per creare un utente di servizio per Klaviyo. Per completare la configurazione seguente devi disporre dei privilegi security admin e sysadmin. Per rivedere i ruoli che hai, esegui SHOW GRANTS TO USER <your_username> e assicurati di aver elencato entrambi i ruoli. Se devi modificare il tuo ruolo, rivolgiti a un amministratore di sistema.
- Non esitare ad aggiornare una qualsiasi delle variabili impostate all'inizio dello script.
- In sintesi, potrai:
- Scegli un magazzino esistente o creane uno nuovo
- Scegli un database esistente o creane uno nuovo per contenere i nuovi schemi
- Crea due nuovi schemi
KLAVIYO_TMPeKLAVIYO_IMPORT_FROM_DWH - Crea un nuovo criterio di rete e consenti l'invio di un elenco di IP Klaviyo
- Crea un utente e un ruolo per Klaviyo
- Lo script è impotente (può essere eseguito più volte), ma non sovrascrive gli oggetti esistenti con nomi in conflitto.
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; Configurazione dei dati Snowflake
Qui sopra, hai creato due nuovi schemi.
- KLAVIYO_TMP sarà utilizzato esclusivamente da Klaviyo. NON DEVI modificare le tabelle create in questo schema. Klaviyo eliminerà queste tabelle quando non saranno più necessarie.
- KLAVIYO_IMPORT_FROM_DWH è il luogo in cui devi archiviare le tabelle finali affinché Klaviyo le importi. Durante il processo di creazione della sincronizzazione, tutte le tabelle di questo schema saranno elencate tra cui potrai scegliere. Pertanto, DOVRESTI memorizzare solo le tabelle finali che desideri importare per evitare confusione durante la configurazione.
Tutte le tabelle che intendi importare in Klaviyo devono soddisfare i seguenti criteri.
Requisiti per la data e l'ora
- Le tabelle DEVONO contenere un campo data e ora che indica quando la riga è stata creata o aggiornata. Spesso questo sarà inserted_at o updated_at. Lo imposterai per ogni tabella durante il processo di creazione della sincronizzazione.
- Il campo della data e dell'ora DEVE aumentare in modo monotono (cioè deve sempre diventare più grande o rimanere lo stesso, mai più piccolo).
- Dopo la creazione della sincronizzazione, NON DEVI impostare il valore della data e dell'ora di una riga su un'ora passata, altrimenti Klaviyo potrebbe non rilevare quella riga.
- Il fuso orario di questo particolare campo non è importante per Klaviyo, purché tu segua i requisiti di cui sopra
- Le tue marche temporali DEVONO essere in UTC o includere le informazioni sul fuso orario. Se mancano le informazioni sul fuso orario, Klaviyo presumerà l'UTC. Per le proprietà personalizzate, questi timestamp rimangono in formato stringa, consentendoti di interpretarli nel tuo fuso orario preferito.
- Il campo Timestamp DEVE riflettere il momento in cui la riga è stata inserita e deve essere raggruppato vicino alla data corrente. Klaviyo sincronizza i dati scansionando le finestre di 1 ora a partire dal valore del timestamp più vecchio della tua tabella. Una singola riga con una data e un'ora lontane nel passato (ad esempio, un record del 2023 quando tutte le altre sono recenti) fa sì che Klaviyo effettui l'iterazione attraverso ogni finestra di 1 ora da quella data in poi in ogni ciclo di sincronizzazione. Si tratta di una limitazione attuale che dovrebbe essere risolta in una prossima versione.
- Considera la densità delle righe per finestra di 1 ora. Poiché i dati vengono caricati in lotti di finestre di data e ora di 1 ora, milioni di record nella stessa finestra di 1 ora possono causare sincronizzazioni lente o bloccate. Sebbene il limite superiore della densità delle righe dipenda dalla quantità di dati in ogni riga, una buona regola da tenere a mente è 100.000 righe per finestra con data e ora.
- Klaviyo consiglia di impostare il campo della data e dell'ora con CURRENT_TIMESTAMP() o una funzione equivalente ogni volta che aggiungi righe alla tabella da cui ci sincronizzeremo. Più righe possono avere lo stesso timestamp. Vedi l'esempio qui sotto.
INSERT INTO table_name AS
SELECT ...
, CURRENT_TIMESTAMP() AS inserted_at
... Struttura della tabella
- Le tabelle DEVONO essere trattate come tabelle di sola aggiunta (dette anche tabelle di sola aggiunta)
- Se preferisci aggiornare le righe in posizione, DEVI aggiornare il campo della data e dell'ora in modo che Klaviyo possa identificare la modifica.
- Le tabelle DOVREBBERO essere ordinate sulla tua colonna della data e dell'ora. Snowflake gestirà il clustering e il partizionamento in base al tuo ordine di inserimento. Questo aiuterà a ottimizzare le richieste di importazione di Klaviyo, mantenendo i costi di calcolo in Snowflake
Unicità e coerenza del profilo
- DEVI assicurarti che ogni Proprietà del profilo sia importata da una sola fonte di dati (tabella). Klaviyo impedisce di selezionare la stessa proprietà da tabelle diverse durante la creazione della sincronizzazione, semplificando questo requisito.
- DOVRESTI utilizzare gli stessi identificatori del profilo (e-mail, numero di telefono, ID esterno, ecc.) in tutte le tabelle di importazione, per ridurre al minimo il rischio di creazione di profili duplicati.
- Klaviyo creerà nuovi profili se l'identificatore del profilo che fornisci non corrisponde a un profilo esistente all'interno di Klaviyo.
- Esempio: tabella 1 (e-mail, colore_fax) + tabella 2 (telefono, compleanno)
- Questo potrebbe creare 2 profili per la stessa persona, se il profilo non esiste attualmente. Se un profilo esiste, Klaviyo gestirà internamente la risoluzione del profilo e gli aggiornamenti.
- Un modo per evitare questo problema è utilizzare una sola tabella di importazione per tutti i tuoi profili.
Prevenzione Circolare Dell'Anello Importazione-Esportazione
- DOVRESTI gestire con attenzione gli scenari in cui vengono utilizzate sia le funzionalità di importazione che quelle di esportazione per evitare loop di importazione-esportazione circolari. Assicurati che il processo di esportazione non reinserisca i dati in una tabella che si trova a monte della tabella di importazione, poiché al momento Klaviyo non rileva questo scenario.
- Klaviyo non ha ancora una logica per rilevare questo scenario.
- Avrebbe un aspetto simile a:
- Ad ogni ciclo di sincronizzazione dell'esportazione, Klaviyo esporta tutti i tuoi profili
- Dopodiché, aggiungi tutti i tuoi profili esportati alla tabella di importazione attraverso alcune serie di trasformazioni.
- Ad ogni ciclo di sincronizzazione dell'importazione, Klaviyo legge tutti i profili nella tua tabella di importazione, che saranno infine riesportati
- Scenari in cui è probabilmente sicuro
- Se utilizzi la tabella Esporta solo per limitare le righe aggiunte alla tabella di importazione
- Se verifichi che la tabella di esportazione non aggiunga righe alla tua tabella di importazione.
- Quali sono le conseguenze di un circuito circolare di importazione-esportazione?
- Ciò comporterà costi di calcolo inutili sia per te che per Klaviyo.
Risoluzione dei problemi
La sincronizzazione sembra bloccata
Se la tua sincronizzazione è in corso, ma i dati non appaiono in Klaviyo dopo diverse ore, o se il completamento della sincronizzazione richiede un tempo insolitamente lungo, la causa più probabile è un valore di data e ora molto lontano nel passato:
- Controlla la tua tabella per verificare la presenza di eventuali righe con una data e un'ora significativamente più vecchie rispetto al resto dei tuoi dati (ad esempio, una riga del 2023 quando tutte le altre risalgono alla settimana precedente). Anche una singola riga anomala costringe Klaviyo a scorrere migliaia di finestre vuote della durata di un'ora prima di raggiungere i dati recenti.
- Correzione: aggiorna o rimuovi qualsiasi riga con marche temporali lontane nel passato o impostale su un valore recente, prima di abilitare o riabilitare la sincronizzazione. Per i backfill, imposta tutte le righe cronologiche sullo stesso timestamp recente (ad esempio, il tempo di esecuzione del job attuale) per ridurre al minimo il numero di finestre di un'ora che Klaviyo deve scansionare. Se il numero di righe è superiore a ~100.000, imposta i timestamp in lotti di ~100.000 ogni (almeno) 61 minuti.
Configurazione consigliata della chiave di clustering Snowflake
Raggruppando la tua tabella Snowflake nella colonna del timestamp, le query di importazione di Klaviyo possono ignorare micropartizioni non necessarie, riducendo sia il tempo di sincronizzazione che i costi di calcolo di Snowflake:
ALTER TABLE your_database.KLAVIYO_IMPORT_FROM_DWH.your_table CLUSTER BY (your_timestamp_column);