Cos'è l'Object Tagging in Snowflake?
L'object tagging in Snowflake è una funzionalità di data governance che permette di categorizzare e raggruppare oggetti (warehouse, tabelle e così via). L'obiettivo è migliorare la reperibilità, monitorare l'utilizzo e tenere sotto controllo la compliance degli oggetti Snowflake. I tag sono particolarmente comodi per individuare oggetti Snowflake che contengono informazioni sensibili, come PII o dati finanziari. Sono inoltre utili per assegnare la proprietà delle risorse, sia ai fini del monitoraggio dei costi sia per la data governance.
Cosa sono i tag?
Per applicare un tag a un oggetto in Snowflake, occorre prima creare il tag stesso.
I tag sono oggetti a livello di schema in Snowflake e possono essere associati ad altri oggetti come database, schemi, tabelle, colonne, utenti, warehouse, ruoli e così via. L'elenco degli oggetti a cui si possono applicare i tag è piuttosto esteso e si trova qui.
Un tag è una coppia chiave-valore. Il nome del tag ( create tag <tag name>) costituisce la "chiave", mentre i valori possono essere definiti tramite una lista predefinita oppure lasciati liberi, accettando qualsiasi stringa.
Per esempio, se si vuole tenere traccia del pubblico di una determinata tabella, si può creare un tag (chiave) chiamato "audience" con valori come HR, Sales, Operations, IT e così via. Questi tag si interrogano con facilità: mostrami tutte le tabelle usate da sales. Lo vedremo più avanti in questo articolo.
Ereditarietà dei tag
Ecco un breve ripasso della " Container Hierarchy" di Snowflake. Un'Organizzazione Snowflake è un contenitore di Account. Un Account è un contenitore di database. Un database è un contenitore di schemi. E uno schema è un contenitore di tabelle, viste, pipe, file format, stage e molti altri oggetti.
Applicando un tag a un oggetto a un qualsiasi livello della gerarchia, il tag viene propagato a tutti gli oggetti sottostanti. Per esempio, se applico un tag a un database, ogni tabella, vista, colonna e altri oggetti come pipe, stage e così via erediteranno il tag del database.
Supponiamo di avere tag impostati esplicitamente a livello di account, database e schema, come in questo esempio:
{
"account": {
"tags": {
"env": "prod",
"region": "us-east-1"
},
"databases": {
"analytics": {
"tags": {
"owner": "data_team",
"classification": "restricted"
},
"schemas": {
"sales": {
"tags": {
Espandi codice
Poiché region è applicato a livello di account, ogni database, schema, tabella, vista e perfino ogni colonna erediteranno il valore us-east-1. Davvero comodo!
Interrogare la lineage dei tag è semplice grazie alla funzione snowflake.account_usage.tag_references_with_lineage, mostrata di seguito. Vedi "Osservare i tag con SQL".
In cosa si differenziano gli Object Tag dai Query Tag?
In Snowflake, un query tag è un singolo valore stringa associato a una query o a una sessione, utile per filtrare e cercare nello storico delle query. I query tag non sono coppie chiave-valore: sono semplicemente stringhe ricercabili. Gli object tag, invece, sono coppie chiave-valore e rientrano nel framework di data governance di Snowflake. Vengono utilizzati per classificare, controllare e audit dell'accesso ad asset di dati come tabelle, colonne o schemi.
Quando qualcuno parla di "tagging" in Snowflake, conviene sempre chiarire se si tratta di query tag o di object tag, perché hanno finalità molto diverse.
Come usare i tag in Snowflake
Creare un tag
La sintassi per creare un tag è semplicissima: create tag <tag_name> <allowed values>;
Poiché i tag sono oggetti a livello di schema, conviene usare SQL completamente qualificato o prestare attenzione al contesto del worksheet. Come per qualsiasi cosa in Snowflake, i tag possono essere creati in un database (o schema) e usati in un altro.
Esempi:
use schema governance.tags;
create tag table_classification allowed_values 'metadata', 'fact', 'dimension';
-- crea un tag con una lista specifica di valori consentiti.
create tag user_group;
-- crea un tag che accetta qualsiasi valore.
Creare un tag senza specificare i valori consentiti imposta il parametro allowed_values su null, lasciando la possibilità di applicare qualsiasi stringa di testo come valore. È comodo quando l'elenco dei valori deve essere dinamico, ma nella maggior parte dei casi conviene elencare in anticipo i valori consentiti e usare alter sul tag quando occorre aggiungerne altri.
Verificare i valori consentiti di un tag
Per controllare i valori consentiti di un tag esistente ci sono diversi modi semplici.
Il comando show tags; restituisce i metadati di tutti i tag dell'account. Una delle colonne restituite è allowed_values.
Un altro modo è chiamare la system function system$get_tag_allowed_values per un tag specifico.
select system$get_tag_allowed_values(
'governance.tags.cost_center');
Un'ulteriore alternativa è la funzione get_ddl di Snowflake. Per esempio:
1select get_ddl('tag','dev.public.TESTING_TAG_1');
Applicare un tag a un oggetto
Per impostare un tag su un oggetto si usa il comando alter. Per esempio, per applicare un tag alla tabella select_blog.workday.workday_users:
alter table select_blog.workday.workday_users
set tag tutorial_db.public.table_classification = 'metadata';
In questo esempio il tag è creato in un database chiamato tutorial_db e viene utilizzato in un database chiamato select_blog.
Osservare i tag di Snowflake con SQL
Opzione 1: interrogare la vista account_usage.tag_references
La vista snowflake.account_usage.tag_references mostra ogni punto in cui un tag è applicato e qual è il suo valore. Le colonne più usate per filtrare sono tag_name e tag_value. Questa tabella non riflette l'ereditarietà dei tag: mostra soltanto gli oggetti a cui un tag è stato applicato direttamente.
SELECT * FROM
snowflake.account_usage.tag_references
where tag_name ilike 'table_class%'
or tag_value ilike 'meta%'
ORDER BY TAG_NAME, DOMAIN, OBJECT_ID;
Attenzione: i dati di questa vista hanno un ritardo significativo. La documentazione Snowflake indica che possono essere posticipati fino a due ore. Nella mia esperienza, nella maggior parte dei casi il ritardo è di almeno un'ora.
Opzione 2: la funzione get_tag
Poiché la vista snowflake.account_usage.tag_references è soggetta a ritardo, a volte serve un modo rapido per osservare immediatamente le modifiche agli oggetti taggati. La system function system$get_tag è sempre aggiornata.
Sintassi:
SELECT SYSTEM$GET_TAG( <fully qualified tag name>,
<'fully qualified object name'>, <'object class such as table, view, etc' > )
AS TAG_META;
Esempio:
SELECT SYSTEM$GET_TAG( 'tutorial_db.public.table_classification',
'SELECT_BLOG.WORKDAY.WORKDAY_USERS', 'TABLE' )
AS TAG_META;
Opzione 3: la funzione account_usage.tag_lineage
In precedenza abbiamo parlato di "ereditarietà dei tag": i tag vengono propagati automaticamente dai livelli più alti a quelli più bassi. La funzione tag_lineage consente di visualizzare tutti gli oggetti che hanno ricevuto un tag, sia direttamente sia per ereditarietà. Proseguendo con l'esempio di table_classification, possiamo scrivere questo SQL:
SELECT *
FROM TABLE(
snowflake.account_usage.tag_references_with_lineage(
'TUTORIAL_DB.PUBLIC.TABLE_CLASSIFICATION'
)
);
Qui si vede che il tag è stato applicato manualmente alla tabella WORKDAY_USERS e che ogni colonna della tabella eredita il tag.
In questo screenshot molte colonne sono state nascoste nell'interfaccia di Snowsight per far entrare tutto nell'immagine.
Osservare i tag di Snowflake dall'interfaccia di Snowsight
Snowflake mette a disposizione una comoda dashboard da cui è possibile osservare tutti i tag presenti nell'account.
Usando il ruolo accountadmin oppure un ruolo configurato correttamente per accedere alla dashboard, è sufficiente usare la barra laterale di Snowsight e andare su Monitoring —> Governance.
Di seguito un'anteprima della dashboard. Trattandosi di un account demo, non ci sono tag impostati, ma se ne intuisce l'utilità.
Cliccando sulla scheda "Tagged Objects" si vedono tutte le tabelle e le viste dell'account e i tag applicati. Gli oggetti sono elencati anche quando non hanno alcun tag. Purtroppo qui non compaiono oggetti come utenti e warehouse. Snowflake offre buone opzioni di filtraggio in questa pagina: vale la pena esplorarle.
Attiva il filtro "has tags" per visualizzare solo gli oggetti con tag:
Best practice per il tagging in Snowflake
Definire una policy di tagging centralizzata
Gestire la data governance, le PII e i dati sensibili non è semplice. Si tratta di un'attività in larga parte non tecnica, che richiede molto confronto e allineamento!
Il primo passo è definire una strategia ben strutturata. Ecco alcune domande da cui partire.
- Cosa vogliamo ottenere con i tag? (reportistica dei costi, protezione dei dati sensibili e così via)
- Chi definisce l'elenco dei tag e dei valori consentiti? (Strategia)
- Quali ruoli possono impostare i tag e chi ottiene questi ruoli? (Tattica)
- Come possiamo sfruttare l'ereditarietà dei tag nel modo più efficace?
Sfruttare gli Allowed Values per i tag
Soprattutto quando i tag vengono impostati manualmente, conviene sfruttare l'impostazione "allowed values". Quando invece l'assegnazione è automatizzata sulla base dei dati di una tabella, questo aspetto diventa meno critico.
Automatizzare il tagging quando possibile
Il tagging perde efficacia quando i team si affidano all'applicazione manuale. Cercate modalità creative per automatizzarlo. Trovate un esempio qui sotto!
Integrare il tagging con le data pipeline quando possibile
Esiste un utile pacchetto dbt chiamato dbt_tags: aiuta ad automatizzare l'Object Tagging in Snowflake e a coordinare il dynamic masking in base ai tag. Se vi serve il data masking basato sui tag, vale la pena dargli un'occhiata!
Monitorare e auditare l'uso dei tag
Perché creare tutti quei tag se poi non li si rivede mai?! Dedicate un'ora al mese alla revisione dei tag, del loro utilizzo e all'aggiornamento della policy di tagging.
Automatizzare il tagging in Snowflake: un esempio pratico
Lo scenario
Immaginiamo uno scenario in cui i metadati dei dipendenti sono gestiti in Workday (o nell'ERP che preferite) e quella tabella viene caricata in Snowflake tramite ETL. Chiamiamola workday_users. Contiene una riga per ciascun utente, e ogni colonna rappresenta un attributo che vogliamo mantenere come tag sull'utente Snowflake. Questo ci permette di auditare, monitorare e impostare i permessi sugli utenti che condividono gli stessi tag.
Quando un utente cambia dipartimento o ruolo, i tag in Snowflake dovrebbero aggiornarsi automaticamente.
Creare dei dati di esempio
Creiamo una tabella e qualche dato fittizio per il nostro scenario:
-- Questa tabella rappresenta una tabella caricata via ETL da Workday a Snowflake, contenente i metadati degli utenti
-- Sto usando un database demo, sostituiscilo con il tuo.
create or replace table select_blog.workday.workday_users
(
employee_id text,
work_email text,
manger_email text,
is_manager boolean,
pillar_id text,
group_id text,
team_id text,
department_id text,
job_family_id text,
area text,
cost_center text,
Espandi codice
Popoliamo la tabella con alcuni dati fittizi:
1insert into select_blog.workday.workday_users
2values(
33000,
4'[email protected]',
5null,
6true,
7'Pillar-C-SUITE',
8'Group-C-SUITE',
9'Team-Founders',
10'Department-All',
11'JF-Founders',
12'Founders',
13'CC Board of Directors',
14'CC3625'
15),
Espandi codice
In questo scenario vogliamo trasformare ogni campo che termina con _id in un tag sull'utente Snowflake.
Creare i tag
Supponiamo che il numero di colonne di workday_users sia relativamente stabile e che la creazione dei tag possa essere un'attività una tantum (o comunque poco frequente) che non necessita di automazione. Se viene aggiunta una colonna, possiamo creare un nuovo tag. (In alternativa, si può schedulare il codice qui sotto in un task! Basta non usare "replace" sui tag se lo si schedula.)
Il codice seguente interroga i metadati delle colonne, filtrando quelle che contengono _id, secondo il nostro requisito. Questi nomi di colonna diventano i nomi dei tag. Per ogni colonna _id creiamo semplicemente un nuovo tag. In questo caso non predefiniamo i valori consentiti, perché saranno popolati dai dati.
Questo codice evita di scrivere a mano una dozzina o più di istruzioni create tag. Esegue create or replace tag ... per ogni riga di un'istruzione select.
BEGIN
-- Dichiara le variabili
LET create_tag_statements RESULTSET := (
SELECT
'CREATE OR REPLACE TAG "' || COLUMN_NAME || '" COMMENT = ''Tag for ' || COLUMN_NAME || ''';' AS create_tag_statement
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'WORKDAY_USERS'
AND TABLE_SCHEMA = 'WORKDAY'
AND LOWER(COLUMN_NAME) ILIKE '%_ID'
);
-- Itera sul result set ed esegui ogni istruzione
LET stmt VARCHAR DEFAULT '';
LET create_tag_cursor CURSOR FOR SELECT * FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()));
Espandi codice
In alternativa, è possibile eseguire manualmente comandi come questi:
use schema select_blog.workday;
create tag pillar_id;
create tag team_id;
-- elimina i tag se necessario
drop tag my_obsolete_tag;
Creare una vista che confronti i tag effettivi degli utenti con lo stato desiderato
La tabella workday_users rappresenta lo "stato desiderato", perché contiene le informazioni più aggiornate da Workday su come vogliamo siano impostati i tag degli utenti. Ora dobbiamo confrontare i tag utente effettivi con lo stato desiderato e mostrare le righe i cui tag non sono impostati correttamente. (In questo caso possiamo dare per scontato che la colonna work_email della tabella workday_users corrisponda all'indirizzo email dell'utente Snowflake nella tabella snowflake.account_usage.users.)
Salviamo questa query come vista, dato che la useremo spesso.
create or replace view tag_updates as
with desired_tags as (
select
upper(work_email) as user_email,
upper(tag_name) as tag_name,
replace(upper(desired_tag_value), '-', '_') as desired_tag_value,
from
workday_users unpivot (
desired_tag_value for tag_name in (pillar_id, group_id, group_id)
)
),
snowflake_user_email as (
select
upper(name) as user_name,
Espandi codice
Riassumiamo cosa fa la vista:
- Esegue l'unpivot della tabella workday (genera righe a partire dalle colonne) per ottenere una riga per ciascun utente e per ciascun possibile tag.
- Recupera lo
USER_NAMESnowflake da taggare e l'indirizzo email Snowflake da usare nella join con la tabella dello "stato desiderato". - Esegue la join sull'email per recuperare i tag esistenti di ogni utente.
- Infine, mostra tutti i record in cui il valore del tag esistente è diverso da quello desiderato.
Sono i record che possiamo impostare automaticamente tramite una stored procedure.
Poiché la vista tag_updates filtra le righe in cui il valore del tag esistente non corrisponde a quello desiderato, idealmente è vuota quando i tag sono impostati correttamente.
Creare una stored procedure per impostare i tag sugli utenti
La stored procedure esegue questi passaggi essenziali:
- Per ogni riga della vista
tag_updates:- alter user, set tag = tag desiderato
Qui sotto propongo due versioni della stored procedure. La prima è una versione semplice, senza logging: è molto chiara e di facile lettura. La seconda è più verbosa e serve per il troubleshooting nel caso in cui i tag desiderati non venissero impostati. Include messaggi di output nel pannello dei risultati SQL.
Procedura semplice:
CREATE OR REPLACE PROCEDURE SET_USER_TAGS()
RETURNS VARCHAR
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
PACKAGES = ('snowflake-snowpark-python')
HANDLER = 'main'
AS
$$
def main(session):
query = """
SELECT
user_name as USER_NAME,
tag_name as TAG_NAME,
desired_tag_value as DESIRED_TAG_VALUE
FROM tag_updates
Espandi codice
Sproc verbosa con logging:
-- crea la procedura con un ruolo admin che abbia i permessi per "alter user".
user role accountadmin; -- oppure usa role useradmin se i tuoi utenti appartengono effettivamente a useradmin
-- se usi il ruolo useradmin devi concedere usage a quel ruolo sul database. È quindi più semplice usare accountadmin.
CREATE OR REPLACE PROCEDURE SET_USER_TAGS()
RETURNS VARCHAR
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
PACKAGES = ('snowflake-snowpark-python')
HANDLER = 'main'
AS
$$
def main(session):
# Estrai esattamente le colonne necessarie dalla vista aggiornata
query = """
SELECT
Espandi codice
Chiama la procedura:
1call set_user_tags();
A questo punto fate una pausa pranzo e aspettate un'oretta abbondante (anche di più) che la vista account_usage.tag_references si aggiorni. Se i tag sono impostati correttamente e la vista è stata aggiornata, select * from tag_updates; non restituisce nulla. Esattamente quello che volevamo.
Creare un task per schedulare la stored procedure
Questo task esegue la procedura ogni giorno alle 4:00 UTC.
CREATE TASK set_user_tags
SCHEDULE = 'USING CRON 0 4 * * * UTC' AS
CALL set_user_tags();
alter task set_user_tags resume;
Ed ecco fatto: abbiamo creato un processo per automatizzare i tag sugli utenti a partire dalla tabella di metadati di Workday.
Ora tocca a voi
Questo esempio illustra uno dei tanti scenari di automazione del tagging. In linea con le nostre best practice, però, conviene sempre cercare di automatizzarlo quando è possibile. Il processo sarà sempre lo stesso:
- Definire uno stato desiderato di riferimento.
- Creare i tag (manualmente o in automatico).
- Automatizzare l'impostazione dei tag confrontando lo stato desiderato con quello effettivo.
In sintesi
In questo articolo abbiamo visto a cosa servono i tag in Snowflake, come crearli, le best practice e uno scenario avanzato. Datevi alla creatività! Pensate a come automatizzare il tagging nel vostro account Snowflake!
Jeff è un Data and Analytics Consultant con oltre 15 anni di esperienza nell'automazione degli insight e nell'uso dei dati per governare i processi di business. Sul fronte tecnologico è specializzato in Snowflake + dbt + Tableau. Sul fronte dei settori, vanta esperienza in Public Utility, Clinical Trials, Editoria, CPG e Manifattura. Per qualsiasi contatto: [email protected].