Testare tabelle con asserzioni

Questo documento mostra come utilizzare Dataform core per creare asserzioni delle tabelle Dataform e testare il codice del tuo flusso di lavoro.

Informazioni sulle asserzioni

Un'asserzione è una query di test della qualità dei dati che trova le righe che violano una o più regole specificate nella query. Se la query restituisce delle righe, l'asserzione non riesce. Dataform esegue le asserzioni ogni volta che aggiorna il flusso di lavoro SQL e ti avvisa in caso di esito negativo.

Dataform crea automaticamente viste in BigQuery che contengono i risultati delle query di asserzione compilate. Come configurato nel file delle impostazioni del flusso di lavoro, Dataform crea queste viste in uno schema di asserzioni in cui puoi esaminare i risultati delle asserzioni.

Ad esempio, per lo schema dataform_assertions predefinito, Dataform crea una vista in BigQuery nel seguente formato: dataform_assertions.assertion_name.

Puoi creare asserzioni per tutti i tipi di tabelle Dataform: tabelle, tabelle incrementali, viste e viste materializzate.

Puoi creare asserzioni nei seguenti modi:

Prima di iniziare

  1. Nella console Google Cloud, vai alla pagina Dataform.

    Vai alla pagina Dataform

  2. Seleziona o crea un repository.

  3. Seleziona o crea un'area di lavoro di sviluppo.

  4. Definisci una tabella.

Ruoli obbligatori

Per ottenere le autorizzazioni necessarie per creare le asserzioni, chiedi all'amministratore di concederti il ruolo IAM Editor Dataform (roles/dataform.editor) nelle aree di lavoro. Per saperne di più sulla concessione dei ruoli, consulta Gestire l'accesso.

Potresti anche riuscire a ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.

Crea asserzioni integrate

Puoi aggiungere asserzioni Dataform integrate al blocco config di una tabella. Dataform esegue queste asserzioni dopo la creazione della tabella. Dopo che Dataform ha pubblicato la tabella, puoi controllare l'asserzione.

Puoi creare le seguenti asserzioni nel blocco config di una tabella:

  • nonNull

    Questa condizione asserisce che le colonne specificate non sono nulle in tutte le righe della tabella. Questa condizione viene utilizzata per le colonne che non possono mai essere null.

    Il seguente esempio di codice mostra un'asserzione nonNull nel blocco config di una tabella:

config {
  type: "table",
  assertions: {
    nonNull: ["user_id", "customer_id", "email"]
  }
}
SELECT ...
  • rowConditions

    Questa condizione asserisce che tutte le righe della tabella seguono la logica personalizzata che hai definito. Ogni condizione di riga è un'espressione SQL personalizzata e ogni riga della tabella viene valutata in base a ogni condizione di riga. L'asserzione ha esito negativo se una riga della tabella viola una condizione di riga.

    Il seguente esempio di codice mostra un'asserzione rowConditions personalizzata nel blocco config di una tabella incrementale:

config {
  type: "incremental",
  assertions: {
    rowConditions: [
      'signup_date is null or signup_date > "2022-08-01"',
      'email like "%@%.%"'
    ]
  }
}
SELECT ...
  • uniqueKey

    Questa condizione asserisce che, in una colonna specificata, nessuna riga di tabella ha lo stesso valore.

    Il seguente esempio di codice mostra un'asserzione uniqueKey nel blocco config di una vista:

config {
  type: "view",
  assertions: {
    uniqueKey: ["user_id"]
  }
}
SELECT ...
  • uniqueKeys

    Questa condizione asserisce che, nelle colonne specificate, nessuna riga di tabella ha lo stesso valore. L'asserzione ha esito negativo se nella tabella è presente più di una riga con gli stessi valori per tutte le colonne specificate.

    Il seguente esempio di codice mostra un'asserzione uniqueKeys nel blocco config di una tabella:

config {
  type: "table",
  assertions: {
    uniqueKeys: [["user_id"], ["signup_date", "customer_id"]]
  }
}
SELECT ...

Aggiungi asserzioni al blocco config

Per aggiungere asserzioni al blocco di configurazione di una tabella:

  1. Nell'area di lavoro di sviluppo, nel riquadro File, seleziona un file SQLX di definizione della tabella.
  2. Nel blocco config del file della tabella, inserisci assertions: {}.
  3. All'interno di assertions: {}, aggiungi le tue asserzioni.
  4. (Facoltativo) Fai clic su Formato.

Il seguente esempio di codice mostra le condizioni aggiunte nel blocco config:

config {
  type: "table",
  assertions: {
    uniqueKey: ["user_id"],
    nonNull: ["user_id", "customer_id"],
    rowConditions: [
      'signup_date is null or signup_date > "2019-01-01"',
      'email like "%@%.%"'
    ]
  }
}
SELECT ...

Creare asserzioni manuali con SQLX

Le asserzioni manuali sono query SQL che scrivi in un file SQLX dedicato. Una query SQL di asserzione manuale deve restituire zero righe. Se la query restituisce righe quando viene eseguita, l'asserzione ha esito negativo.

Per aggiungere asserzioni manuali in un nuovo file SQLX, segui questi passaggi:

  1. Nel riquadro File, accanto a definitions/, fai clic sul menu Altro .
  2. Fai clic su Crea file.
  3. Nel campo Aggiungi un percorso file, inserisci il nome del file seguito da .sqlx. Ad esempio: definitions/custom_assertion.sqlx.

    I nomi file possono contenere solo numeri, lettere, trattini e trattini bassi.

  4. Fai clic su Crea file.

  5. Nel riquadro File, fai clic sul nuovo file.

  6. Nel file, inserisci:

    config {
      type: "assertion"
    }
    
  7. Sotto il blocco config, scrivi la tua query SQL o più query.

  8. (Facoltativo) Fai clic su Formato.

L'esempio di codice seguente mostra un'asserzione manuale in un file SQLX che asserisce che i campi A, B e c non sono mai NULL in sometable:

config { type: "assertion" }

SELECT
  *
FROM
  ${ref("sometable")}
WHERE
  a IS NULL
  OR b IS NULL
  OR c IS NULL

Imposta le asserzioni come dipendenze

Quando l'azione B del flusso di lavoro dipende dall'azione A del flusso di lavoro che ha asserzioni, il mancato funzionamento delle asserzioni dell'azione A non impedisce a Dataform di eseguire l'azione B. Per eseguire l'azione B solo se le asserzioni dell'azione A passano, devi impostare le asserzioni dell'azione A come dipendenze dell'azione B.

Puoi impostare le asserzioni come dipendenze di un'azione selezionata nei seguenti modi:

Imposta le asserzioni selezionate come dipendenze

Puoi impostare manualmente le asserzioni selezionate come dipendenze aggiungendole a dependencies: [ "" ] nel blocco config dell'azione modificata.

Ad esempio, se l'azione B dipende dall'azione A e vuoi che l'azione B dipenda solo dalle asserzioni selezionate dell'azione A, puoi aggiungere queste asserzioni selezionate al blocco di azione B config.

Puoi impostare manualmente le asserzioni selezionate come dipendenze per tutti i tipi di azioni, ad eccezione delle dichiarazioni dell'origine dati.

Imposta le asserzioni di un'azione di dipendenza selezionata come dipendenze

Puoi impostare il parametro includeDependentAssertions per impostare automaticamente tutte le asserzioni dirette di un'azione del flusso di lavoro delle dipendenze selezionata come dipendenze dell'azione modificata. Dataform aggiunge queste asserzioni come dipendenze durante ogni compilazione dell'azione per garantire che le dipendenze siano aggiornate se le asserzioni dell'azione di dipendenza cambiano.

Ad esempio, se l'azione C dipende dalle azioni A e B, ma vuoi che solo l'azione C dipenda dalle asserzioni dell'azione A, puoi modificare l'azione C e impostare il parametro includeDependentAssertions in modo da impostare automaticamente tutte le asserzioni dell'azione A come dipendenze dell'azione C.

Puoi impostare il parametro includeDependentAssertions per azioni dei seguenti tipi:

  • table
  • view
  • operations
Imposta le asserzioni di tutte le azioni di dipendenza come dipendenze

Puoi impostare il parametro dependOnDependencyAssertions in modo che imposti automaticamente tutte le asserzioni dirette di tutte le azioni di dipendenza dell'azione modificata come dipendenze aggiuntive dell'azione modificata. Dataform aggiunge queste asserzioni come dipendenze durante ogni compilazione dell'azione per garantire che le dipendenze siano aggiornate se le asserzioni dell'azione di dipendenza cambiano.

Ad esempio, se l'azione C dipende dalle azioni A e B, puoi modificare l'azione C e impostare il parametro dependOnDependencyAssertions in modo da impostare automaticamente tutte le asserzioni delle azioni A e B come dipendenze dell'azione C.

Puoi impostare il parametro dependOnDependencyAssertions per azioni dei seguenti tipi:

  • table
  • view
  • operations

Quando imposti il parametro dependOnDependencyAssertions e i parametri includeDependentAssertions in un singolo file, il parametro includeDependentAssertions ha la priorità. Ad esempio, se imposti dependOnDependencyAssertions su true, ma imposti anche includeDependentAssertions su false per un'azione di dipendenza selezionata, Dataform non aggiungerà le asserzioni di questa azione alle dipendenze.

Il seguente esempio di codice mostra i parametri dependOnDependencyAssertions e includeDependentAssertions impostati nello stesso file di definizione della tabella:

// filename is tableName.sqlx

config {
type: "table",
dependOnDependencyAssertions: true,
dependencies: [ "actionA", {name: "actionB", includeDependentAssertions: false} ]
}

SELECT * FROM ${ref("actionC")}

Nell'esempio di codice precedente, Dataform aggiunge tutte le asserzioni dirette di actionA e actionC alle dipendenze di tableName durante la compilazione.

Imposta le asserzioni selezionate come dipendenze

Per eseguire un'azione del flusso di lavoro solo quando le asserzioni selezionate vengono superate, puoi aggiungere l'asserzione selezionata a dependencies: [ "" ] nel blocco config dell'azione modificata.

Per impostare un'asserzione selezionata come dipendenza da un'azione del flusso di lavoro selezionata: segui questi passaggi:

  1. Nell'area di lavoro di sviluppo, espandi definitions/ nel riquadro File.
  2. Seleziona un file SQLX di azione del flusso di lavoro.
  3. Nel blocco config del file delle azioni, inserisci dependencies: [ "" ].
  4. All'interno di dependencies: [ "" ], inserisci il nome dell'asserzione dell'azione o il nome del file dell'asserzione manuale che vuoi impostare come dipendenza in uno dei seguenti formati:

    nonNull

    config {
      type: "ACTION_TYPE",
      dependencies: [ "ACTION_DATASET_NAME_ACTION_NAME_assertions_nonNull"]
    }
    

    Sostituisci quanto segue:

    • ACTION_TYPE: il tipo di azione del flusso di lavoro: table, view o operations.
    • ACTION_DATASET_NAME: il nome del set di dati in cui è definita l'azione. Il set di dati predefinito è definito nel file delle impostazioni del flusso di lavoro.
    • ACTION_NAME: il nome dell'azione in cui è definita l'asserzione.

    rowConditions

    config {
      type: "ACTION_TYPE",
      dependencies: [ "ACTION_DATASET_NAME_ACTION_NAME_assertions_rowConditions"]
    }
    

    Sostituisci quanto segue:

    • ACTION_TYPE: il tipo di azione del flusso di lavoro: table, view o operations.
    • DATASET_NAME: il nome del set di dati in cui è definita l'azione. Il set di dati predefinito è definito nel file delle impostazioni del flusso di lavoro.
    • ACTION_NAME: il nome dell'azione in cui è definita l'asserzione.

    uniqueKey

    config {
      type: "ACTION_TYPE",
      dependencies: [ "ACTION_DATASET_NAME_ACTION_NAME_assertions_uniqueKey_INDEX"]
    }
    

    Sostituisci quanto segue:

    • ACTION_TYPE: il tipo di azione del flusso di lavoro: table, view o operations.
    • DATASET_NAME: il nome del set di dati in cui è definita la tabella. Il set di dati predefinito è definito nel file delle impostazioni del flusso di lavoro.
    • ACTION_NAME: il nome della tabella in cui è definita l'asserzione.
    • INDEX: l'indice dell'array di chiavi definito nell'asserzione uniqueKey che vuoi aggiungere come dipendenza. Ad esempio, 0 o 1. Se nell'asserzione è definito un solo array di chiavi, l'indice è 0.

    uniqueKeys

    config {
      type: "ACTION_TYPE",
      dependencies: [ "ACTION_DATASET_NAME_ACTION_NAME_assertions_uniqueKeys_INDEX"]
    }
    

    Sostituisci quanto segue:

    • ACTION_TYPE: il tipo di azione del flusso di lavoro: table, view o operations.
    • DATASET_NAME: il nome del set di dati in cui è definita la tabella. Il set di dati predefinito è definito nel file delle impostazioni del flusso di lavoro.
    • ACTION_NAME: il nome della tabella in cui è definita l'asserzione.
    • INDEX: l'indice dell'array di chiavi definito nell'asserzione uniqueKeys che vuoi aggiungere come dipendenza, ad esempio 0 o 1. Se nell'asserzione è definito un solo array di chiavi, l'indice è 0.

    asserzione manuale

    config {
      type: "ACTION_TYPE",
      dependencies: [ "MANUAL_ASSERTION_NAME"]
    }
    

    Sostituisci quanto segue:

    • ACTION_TYPE: il tipo di azione del flusso di lavoro: table, view o operations.
    • MANUAL_ASSERTION_NAME il nome dell'asserzione manuale.
  5. Per aggiungere un'altra asserzione come dipendenza alla tabella modificata, ripeti il Passaggio 4.

  6. (Facoltativo) Fai clic su Formato.

Il seguente esempio di codice mostra le asserzioni aggiunte alla tabella A, definita nel set di dati dataform:

config {
  type: "table",
  assertions: {
    uniqueKey: ["user_id"],
    nonNull: ["user_id", "customer_id"],
  }
}

Il seguente esempio di codice mostra le asserzioni della tabella A aggiunte come dipendenze alla tabella B:

config {
  type: "table",
  dependencies: [ "dataform_A_assertions_uniqueKey_0",  "dataform_A_assertions_nonNull"]
}

Il seguente esempio di codice mostra un'asserzione manuale definita nel file manualAssertion.sqlx, aggiunta come dipendenza a una vista:

config {
  type: "view",
  dependencies: [ "manualAssertion"]
}

Il seguente esempio di codice mostra il file manual_assertion e le asserzioni della tabella sometable aggiunte come dipendenze di una tabella:

config {
  type: "table",
  dependencies: [ "manual_assertion",  "dataform_sometable_assertions_nonNull" ,  "dataform_sometable_assertions_rowConditions"]
}

SELECT * FROM ${ref("referenced_table")} LEFT JOIN ...

Imposta le asserzioni di un'azione selezionata come dipendenze

Per eseguire un'azione del flusso di lavoro solo quando tutte le asserzioni dirette di un'azione di dipendenza selezionata vengono superate, imposta il parametro includeDependentAssertions su true nell'azione modificata. Dataform aggiunge automaticamente alle dipendenze le asserzioni dirette dell'azione di dipendenza selezionata durante la compilazione. Il valore predefinito è false.

Per impostare come dipendenze tutte le asserzioni di un'azione di dipendenza selezionata:

  1. Nell'area di lavoro di sviluppo, espandi definitions/ nel riquadro File.
  2. Seleziona un file SQLX di azione del flusso di lavoro.
  3. Nel file, imposta il parametro includeDependentAssertions su true in uno dei seguenti modi:

    Nel blocco config

    config {
    type: "ACTION_TYPE",
    dependencies: [{name: "dEPENDENCY_ACTION_NAME", includeDependentAssertions: true}]
    }
    

    Sostituisci quanto segue:

    • ACTION_TYPE: il tipo di azione del flusso di lavoro: table, view o operations.
    • DEPENDENCY_ACTION_NAME: il nome dell'azione di dipendenza dalle asserzioni che vuoi impostare come dipendenze dell'azione modificata.

    Nell'istruzione SELECT

      config { type: "ACTION_TYPE" }
    
      SELECT * FROM ${ref({name: "DEPENDENCY_ACTION_NAME", includeDependentAssertions: true})}
    

    Sostituisci quanto segue:

    • ACTION_TYPE: il tipo di azione del flusso di lavoro: table, view o operations.
    • DEPENDENCY_ACTION_NAME: il nome dell'azione di dipendenza dalle asserzioni che vuoi impostare come dipendenze dell'azione modificata.
  4. (Facoltativo) Fai clic su Formato.

Il seguente esempio di codice mostra l'elemento tableC che dipende da viewA, tableB e da tutte le asserzioni di tableB:

// filename is tableC.sqlx

config {
type: "table",
dependencies: ["viewA", {name: "tableB", includeDependentAssertions: true}]
}

SELECT * FROM ...

Nell'esempio di codice precedente, Dataform aggiunge automaticamente tutte le asserzioni dirette di tableB come dipendenze a tableC durante la compilazione.

Imposta le asserzioni di tutte le azioni di dipendenza come dipendenze

Per eseguire un'azione del flusso di lavoro solo quando vengono superate tutte le asserzioni dirette di tutte le azioni di dipendenza, imposta il parametro dependOnDependencyAssertions su true nell'azione modificata. Dataform aggiunge automaticamente asserzioni dirette delle azioni di dipendenza come dipendenze durante la compilazione. Il valore predefinito è false.

Quando imposti il parametro dependOnDependencyAssertions e i parametri includeDependentAssertions in un singolo file, il parametro includeDependentAssertions ha la priorità per l'azione di dipendenza per cui è impostato.

Per impostare come dipendenze tutte le asserzioni di un'azione di dipendenza selezionata:

  1. Nell'area di lavoro di sviluppo, espandi definitions/ nel riquadro File.
  2. Seleziona un file SQLX di azione del flusso di lavoro.
  3. Nel file, imposta il parametro dependOnDependencyAssertions su true nel seguente formato:

    config {
    type: "ACTION_TYPE",
    dependOnDependencyAssertions: true,
    dependencies: [ "dependency1", "dependency2" ]
    }
    

    Sostituisci ACTION_TYPE: il tipo di azione del flusso di lavoro. I valori supportati includono table, view e operations.

  4. (Facoltativo) Fai clic su Formato.

Il seguente esempio di codice mostra l'elemento sometableE che dipende da sometableA, sometabletableB, sometableC e sometableD e da tutte le asserzioni dirette delle tabelle delle dipendenze:

// filename is sometableE.sqlx

config {
type: "table",
dependOnDependencyAssertions: true,
dependencies: [ "sometableA", "sometableB" ]
}

SELECT * FROM ${ref("sometableC")}
SELECT * FROM ${ref("sometableD")}

Nell'esempio di codice precedente, Dataform aggiunge automaticamente tutte le asserzioni dirette di sometableA, sometableB, sometableC e sometableD come dipendenze a sometableE durante la compilazione.

Passaggi successivi