Testar tabelas com declarações

Neste documento, mostramos como usar o Dataform Core para criar declarações de tabelas do Dataform e testar o código do fluxo de trabalho.

Sobre declarações

Uma declaração é uma consulta de teste de qualidade de dados que encontra linhas que violam uma ou mais regras especificadas na consulta. Se a consulta retornar alguma linha, a declaração falhará. O Dataform executa declarações sempre que atualiza seu fluxo de trabalho SQL e alerta você se alguma declaração falhar.

O Dataform cria automaticamente visualizações no BigQuery que contêm os resultados de consultas de declaração compiladas. Conforme configurado no arquivo de configurações do fluxo de trabalho, o Dataform cria essas visualizações em um esquema de declarações em que você pode inspecionar os resultados delas.

Por exemplo, para o esquema dataform_assertions padrão, o Dataform cria uma visualização no BigQuery no seguinte formato: dataform_assertions.assertion_name.

É possível criar declarações para todos os tipos de tabela do Dataform: tabelas, tabelas incrementais, visualizações e visualizações materializadas.

Você pode criar declarações das seguintes maneiras:

Antes de começar

  1. No Console do Google Cloud, acesse a página Dataform.

    Acessar a página do Dataform

  2. Selecione ou crie um repositório.

  3. Selecione ou crie um espaço de trabalho de desenvolvimento.

  4. Definir uma tabela.

Funções exigidas

Para ter as permissões necessárias para criar declarações, peça ao administrador para conceder a você o papel do IAM Editor do Dataform (roles/dataform.editor) nos espaços de trabalho. Para mais informações sobre como conceder papéis, consulte Gerenciar acesso.

Também é possível receber as permissões necessárias com papéis personalizados ou outros papéis predefinidos.

Criar declarações integradas

É possível adicionar declarações integradas do Dataform ao bloco config de uma tabela. O Dataform executa essas declarações após a criação da tabela. Depois que o Dataform publica a tabela, é possível inspecionar a declaração.

Você pode criar as seguintes declarações no bloco config de uma tabela:

  • nonNull

    Essa condição declara que as colunas especificadas não são nulas em todas as linhas da tabela. Essa condição é usada para colunas que nunca podem ser nulas.

    O exemplo de código a seguir mostra uma declaração nonNull no bloco config de uma tabela:

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

    Essa condição declara que todas as linhas da tabela seguem a lógica personalizada que você definiu. Cada condição de linha é uma expressão SQL personalizada, e cada linha da tabela é avaliada em relação a cada condição de linha. A declaração falhará se qualquer linha da tabela violar qualquer condição de linha.

    O exemplo de código abaixo mostra uma declaração rowConditions personalizada no bloco config de uma tabela incremental:

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

    Essa condição declara que, em uma coluna especificada, nenhuma linha da tabela tem o mesmo valor.

    O exemplo de código abaixo mostra uma declaração uniqueKey no bloco config de uma visualização:

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

    Essa condição declara que, nas colunas especificadas, nenhuma linha da tabela tem o mesmo valor. A declaração falhará se houver mais de uma linha na tabela com os mesmos valores para todas as colunas especificadas.

    O exemplo de código a seguir mostra uma declaração uniqueKeys no bloco config de uma tabela:

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

Adicione declarações ao bloco config

Para adicionar declarações ao bloco de configuração de uma tabela, siga estas etapas:

  1. No espaço de trabalho de desenvolvimento, no painel Arquivos, selecione um arquivo SQLX de definição de tabela.
  2. No bloco config do arquivo da tabela, insira assertions: {}.
  3. Dentro de assertions: {}, adicione suas declarações.
  4. Opcional: clique em Formatar.

O exemplo de código a seguir mostra as condições adicionadas ao bloco 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 ...

Criar declarações manuais com SQLX

As declarações manuais são consultas SQL que você escreve em um arquivo SQLX dedicado. Uma consulta SQL de declaração manual não pode retornar linhas. Se a consulta retornar linhas quando executada, a declaração falhará.

Para adicionar declarações manuais em um novo arquivo SQLX, siga estas etapas:

  1. No painel Arquivos, ao lado de definitions/, clique no menu Mais .
  2. Clique em Criar arquivo.
  3. No campo Add a file path, insira o nome do arquivo seguido de .sqlx. Por exemplo, definitions/custom_assertion.sqlx.

    Os nomes de arquivos podem incluir apenas números, letras, hifens e sublinhados.

  4. Clique em Criar arquivo.

  5. No painel Arquivos, clique no novo arquivo.

  6. No arquivo, digite:

    config {
      type: "assertion"
    }
    
  7. Abaixo do bloco config, escreva sua consulta SQL ou várias consultas.

  8. Opcional: clique em Formatar.

O exemplo de código a seguir mostra uma declaração manual em um arquivo SQLX que declara que os campos A, B e c nunca são NULL em sometable:

config { type: "assertion" }

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

Definir declarações como dependências

Quando a ação de fluxo de trabalho B depende da ação A que tem declarações, a falha de declarações da ação A não impede que o Dataform execute a ação B. Para executar a ação B somente se as declarações da ação A forem aprovadas, você precisará definir declarações de ação A como dependências da ação B.

Você pode definir declarações como dependências de uma ação selecionada das seguintes maneiras:

Definir declarações selecionadas como dependências

Você pode definir manualmente as declarações selecionadas como dependências, adicionando-as a dependencies: [ "" ] no bloco config da ação editada.

Por exemplo, se a ação B depender da ação A e você quiser que a ação B dependa apenas de declarações selecionadas da ação A, adicione essas declarações selecionadas ao bloco config de ação B.

Você pode definir manualmente as declarações selecionadas como dependências para todos os tipos de ação, exceto declarações de fonte de dados.

Definir declarações de uma ação de dependência selecionada como dependências

É possível definir o parâmetro includeDependentAssertions para definir automaticamente todas as declarações diretas de uma ação de fluxo de trabalho de dependência selecionada como dependências da ação editada. O Dataform adiciona essas declarações como dependências durante cada compilação da ação para garantir que as dependências estejam atualizadas se as declarações da ação de dependência mudarem.

Por exemplo, se a ação C depender das ações A e B, mas você só quiser que a ação C dependa de declarações da ação A, será possível editar a ação C e definir o parâmetro includeDependentAssertions para definir automaticamente todas as declarações de ação A como dependências da ação C.

É possível definir o parâmetro includeDependentAssertions para ações dos seguintes tipos:

  • table
  • view
  • operations
Definir declarações de todas as ações de dependência como dependências

É possível definir o parâmetro dependOnDependencyAssertions para definir automaticamente todas as declarações diretas de todas as ações de dependência da ação editada como dependências extras da ação editada. O Dataform adiciona essas declarações como dependências durante cada compilação da ação para garantir que as dependências estejam atualizadas se as declarações da ação de dependência mudarem.

Por exemplo, se a ação C depender das ações A e B, será possível editar a ação C e definir o parâmetro dependOnDependencyAssertions para definir automaticamente todas as declarações das ações A e B como dependências da ação C.

É possível definir o parâmetro dependOnDependencyAssertions para ações dos seguintes tipos:

  • table
  • view
  • operations

Quando você define os parâmetros dependOnDependencyAssertions e includeDependentAssertions em um único arquivo, o parâmetro includeDependentAssertions tem prioridade. Por exemplo, se você definir dependOnDependencyAssertions como true, mas também definir includeDependentAssertions como false para uma ação de dependência selecionada, o Dataform não vai adicionar declarações dessa ação às dependências.

O exemplo de código a seguir mostra os parâmetros dependOnDependencyAssertions e includeDependentAssertions definidos no mesmo arquivo de definição de tabela:

// filename is tableName.sqlx

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

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

No exemplo de código anterior, o Dataform adiciona todas as declarações diretas de actionA e actionC às dependências de tableName durante a compilação.

Definir declarações selecionadas como dependências

Para executar uma ação de fluxo de trabalho somente quando as declarações selecionadas forem transmitidas, adicione a declaração selecionada ao dependencies: [ "" ] no bloco config da ação editada.

Para definir uma declaração selecionada como uma dependência de uma ação de fluxo de trabalho selecionada, siga estas etapas:

  1. No espaço de trabalho de desenvolvimento, no painel Arquivos, expanda definitions/.
  2. Selecione um arquivo SQLX de ação de fluxo de trabalho.
  3. No bloco config do arquivo de ação, digite dependencies: [ "" ].
  4. Em dependencies: [ "" ], insira o nome da declaração de ação ou o nome do arquivo da declaração manual que você quer definir como uma dependência em um dos seguintes formatos:

    nonNull

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

    Substitua:

    • ACTION_TYPE: o tipo de ação do fluxo de trabalho: table, view ou operations.
    • ACTION_DATASET_NAME: o nome do conjunto de dados em que a ação é definida. O conjunto de dados padrão é definido no arquivo de configurações do fluxo de trabalho.
    • ACTION_NAME: o nome da ação em que a declaração é definida.

    rowConditions

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

    Substitua:

    • ACTION_TYPE: o tipo de ação do fluxo de trabalho: table, view ou operations.
    • DATASET_NAME: o nome do conjunto de dados em que a ação é definida. O conjunto de dados padrão é definido no arquivo de configurações do fluxo de trabalho.
    • ACTION_NAME: o nome da ação em que a declaração é definida.

    uniqueKey

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

    Substitua:

    • ACTION_TYPE: o tipo de ação do fluxo de trabalho: table, view ou operations.
    • DATASET_NAME: o nome do conjunto de dados em que a tabela é definida. O conjunto de dados padrão é definido no arquivo de configurações do fluxo de trabalho.
    • ACTION_NAME: o nome da tabela em que a declaração é definida.
    • INDEX: o índice da matriz de chaves definida na declaração uniqueKey que você quer adicionar como dependência. Por exemplo, 0 ou 1. Se apenas uma matriz de chaves for definida na declaração, o índice será 0.

    uniqueKeys

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

    Substitua:

    • ACTION_TYPE: o tipo de ação do fluxo de trabalho: table, view ou operations.
    • DATASET_NAME: o nome do conjunto de dados em que a tabela é definida. O conjunto de dados padrão é definido no arquivo de configurações do fluxo de trabalho.
    • ACTION_NAME: o nome da tabela em que a declaração é definida.
    • INDEX: o índice da matriz de chaves definida na declaração uniqueKeys que você quer adicionar como dependência, por exemplo, 0 ou 1. Se apenas uma matriz de chaves for definida na declaração, o índice será 0.

    declaração manual

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

    Substitua:

    • ACTION_TYPE: o tipo de ação do fluxo de trabalho: table, view ou operations.
    • MANUAL_ASSERTION_NAME é o nome da declaração manual.
  5. Para adicionar outra declaração como uma dependência à tabela editada, repita a Etapa 4.

  6. Opcional: clique em Formatar.

O exemplo de código a seguir mostra declarações adicionadas à tabela A, definida no conjunto de dados dataform:

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

O exemplo de código a seguir mostra as declarações da tabela A adicionadas como dependências à tabela B:

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

O exemplo de código abaixo mostra uma declaração manual definida no arquivo manualAssertion.sqlx, adicionada como dependência a uma visualização:

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

O exemplo de código a seguir mostra o arquivo manual_assertion e as declarações da tabela sometable adicionadas como dependências a uma tabela:

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

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

Definir declarações de uma ação selecionada como dependências

Para executar uma ação de fluxo de trabalho somente quando todas as declarações diretas de uma ação de dependência selecionada forem aprovadas, defina o parâmetro includeDependentAssertions como true na ação editada. O Dataform adiciona automaticamente declarações diretas da ação de dependência selecionada às dependências durante a compilação. O valor padrão é false.

Para definir todas as declarações de uma ação de dependência selecionada como dependências, siga estas etapas:

  1. No espaço de trabalho de desenvolvimento, no painel Arquivos, expanda definitions/.
  2. Selecione um arquivo SQLX de ação de fluxo de trabalho.
  3. No arquivo, defina o parâmetro includeDependentAssertions como true de uma das seguintes maneiras:

    No bloco config

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

    Substitua:

    • ACTION_TYPE: o tipo de ação do fluxo de trabalho: table, view ou operations.
    • DEPENDENCY_ACTION_NAME: o nome da ação de dependência que as declarações que você quer definir como dependências da ação editada.

    Na instrução SELECT

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

    Substitua:

    • ACTION_TYPE: o tipo de ação do fluxo de trabalho: table, view ou operations.
    • DEPENDENCY_ACTION_NAME: o nome da ação de dependência que as declarações que você quer definir como dependências da ação editada.
  4. Opcional: clique em Formatar.

O exemplo de código a seguir mostra tableC que depende de viewA, tableB e de todas as declarações de tableB:

// filename is tableC.sqlx

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

SELECT * FROM ...

No exemplo de código anterior, o Dataform adiciona automaticamente todas as declarações diretas de tableB como dependências de tableC durante a compilação.

Definir declarações de todas as ações de dependência como dependências

Para executar uma ação de fluxo de trabalho somente quando todas as declarações diretas de todas as ações de dependência forem aprovadas, defina o parâmetro dependOnDependencyAssertions como true na ação editada. O Dataform adiciona automaticamente declarações diretas de ações de dependência como dependências durante a compilação. O valor padrão é false.

Quando você define o parâmetro dependOnDependencyAssertions e os parâmetros includeDependentAssertions em um único arquivo, o parâmetro includeDependentAssertions tem prioridade para a ação de dependência para a qual ele foi definido.

Para definir todas as declarações de uma ação de dependência selecionada como dependências, siga estas etapas:

  1. No espaço de trabalho de desenvolvimento, no painel Arquivos, expanda definitions/.
  2. Selecione um arquivo SQLX de ação de fluxo de trabalho.
  3. No arquivo, defina o parâmetro dependOnDependencyAssertions como true no seguinte formato:

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

    Substitua ACTION_TYPE: o tipo de ação do fluxo de trabalho. Os valores aceitos incluem table, view e operations.

  4. Opcional: clique em Formatar.

O exemplo de código a seguir mostra sometableE que depende de sometableA, sometabletableB, sometableC e sometableD e todas as declarações diretas de tabelas de dependência:

// filename is sometableE.sqlx

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

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

No exemplo de código anterior, o Dataform adiciona automaticamente todas as declarações diretas de sometableA, sometableB, sometableC e sometableD como dependências de sometableE durante a compilação.

A seguir