Usar JavaScript no Dataform

Este documento ajuda você a entender como usar JavaScript para desenvolver fluxos de trabalho no Dataform. Este documento também mostra como usar JavaScript para criar ações de fluxo de trabalho e como criar inclusões de JavaScript para reutilizar código no Dataform.

Com o Dataform Core, é possível criar ações de fluxo de trabalho com SQLX e JavaScript. Embora seja opcional, use JavaScript com SQLX para criar elementos semelhantes repetidamente no seu fluxo de trabalho. Por exemplo, com JavaScript, é possível criar uma visualização de cada tabela no fluxo de trabalho com determinados IDs de usuário removidos. Também é possível desenvolver ações de fluxo de trabalho exclusivamente com JavaScript.

Antes de começar

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

    Acesse o Dataform

  2. Selecione ou crie um repositório.

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

Além disso, você precisa conhecer a sintaxe do JavaScript e os seguintes conceitos:

  • Variáveis
  • Matrizes
  • Instruções condicionais
  • Repetições for
  • Maps
  • Funções
  • Objetos
  • Como exportar e importar módulos

Funções exigidas

Para receber as permissões necessárias para desenvolver um fluxo de trabalho com JavaScript e reutilizar código com inclusões em JavaScript, peça ao administrador que conceda a você o papel do IAM Editor do Dataform (roles/dataform.editor) em espaços de trabalho. Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

Também é possível conseguir as permissões necessárias por meio de papéis personalizados ou de outros papéis predefinidos.

Adicionar código JavaScript a um arquivo SQLX

É possível adicionar código JavaScript a um arquivo SQLX de duas maneiras: inline ou dentro de um bloco JavaScript.

É possível usar um bloco JavaScript para definir funções ou constantes em um arquivo SQLX. É possível usar JavaScript inline para modificar dinamicamente uma consulta SQLX ou SQL.

O exemplo de código a seguir mostra a função JavaScript integrada do núcleo do Dataform self adicionada inline ao bloco post_operations em um arquivo SQLX:

config {type: "table"}

SELECT * FROM ...

post_operations {
  GRANT `roles/bigquery.dataViewer`
  ON
  TABLE ${self()}
  TO "group:allusers@example.com", "user:otheruser@example.com"
}

O exemplo de código a seguir mostra uma constante definida em um bloco JavaScript e usada inline em uma consulta em um arquivo SQLX:

js {
  const columnName = "foo";
}

SELECT 1 AS ${columnName} FROM "..."

Reutilizar código em um único arquivo SQLX com encapsulamento em JavaScript

É possível reutilizar o código JavaScript para simplificar o desenvolvimento no Dataform. Para reutilizar constantes e funções JavaScript em um único arquivo SQLX, encapsule-as em um bloco JavaScript. Para reutilizar o código JavaScript em um único repositório do Dataform, crie inclusões. Para reutilizar o código JavaScript em vários repositórios do Dataform, crie ou importe um pacote.

Para criar partes repetitivas de código SQL que podem ser reutilizadas em um único arquivo SQLX, encapsule funções e constantes em um bloco JavaScript. É possível reutilizar o código definido em um bloco JavaScript apenas dentro do arquivo SQLX em que o bloco está definido. Para mais informações, consulte Dataform Core.

O exemplo de código a seguir mostra uma constante e uma função definidas em um bloco de JavaScript e usadas inline em uma consulta em um arquivo SQLX:

js {
 const foo = 1;
 function bar(number){
     return number+1;
 }
}

select
 ${foo} as one,
 ${bar(foo)} as two

Reutilizar código em um único repositório com inclusões

Os includes são constantes ou funções globais do JavaScript no seu repositório. Você define inclusões no diretório includes do seu repositório. Depois, é possível reutilizá-los em todo o repositório em arquivos JavaScript e SQLX.

O exemplo de código a seguir mostra a definição da constante launch_date no arquivo includes/constants.js:

// filename is includes/constants.js
const launch_date = "11.11.2011";
module.exports = { launch_date };

O exemplo de código a seguir mostra a constante launch_date referenciada em uma consulta de definição de tabela em um arquivo SQLX:

config {type: "table"}

SELECT * FROM source_table WHERE date > ${constants.launch_date}

Criar um arquivo JavaScript para inclusões

Para criar um arquivo JavaScript no diretório includes/, siga estas etapas:

  1. No painel Arquivos, ao lado de includes/, clique em Mais.

  2. Selecione Criar arquivo.

  3. No painel Criar novo arquivo, faça o seguinte:

    1. No campo Adicionar um caminho de arquivo, depois de includes/, insira o nome do arquivo seguido por .js. Por exemplo, includes/constants.js.

      Os nomes de arquivo só podem incluir números, letras, hifens e sublinhados.

    2. Selecione Criar arquivo.

Criar uma constante JavaScript

Para criar uma constante que pode ser reutilizada em todo o projeto, siga estas etapas:

  1. Acesse o espaço de trabalho de desenvolvimento.

  2. No painel Arquivos, expanda includes/.

  3. Crie ou selecione um arquivo JavaScript com a extensão .js.

  4. No arquivo, digite este snippet de código:

     const CONSTANT_NAME = CONSTANT_VALUE;
     module.exports = { CONSTANT_NAME };
    

    Substitua:

    • CONSTANT_NAME: o nome da constante
    • CONSTANT_VALUE: o valor da sua constante
  5. Opcional: clique em Formatar.

O exemplo de código a seguir define a constante PROJECT_ID no arquivo includes/constants.js:

  // filename is includes/constants.js
  const PROJECT_ID = "my_project_name";
  module.exports = { PROJECT_ID };

O exemplo de código a seguir faz referência à constante PROJECT_ID em uma consulta de definição de tabela em um arquivo SQLX:

  config { type: "table" }
  SELECT * FROM ${constants.PROJECT_ID}.my_schema_name.my_table_name

O exemplo de código a seguir mostra a consulta de definição da tabela principal do Dataform anterior compilada em SQL:

  SELECT * FROM my_project_name.my_schema_name.my_table_name

Criar uma função JavaScript personalizada

Para criar uma função JavaScript personalizada que pode ser reutilizada em todo o projeto, siga estas etapas:

  1. Acesse o espaço de trabalho de desenvolvimento.

  2. No painel Arquivos, expanda includes/.

  3. Crie ou selecione um arquivo JavaScript com a extensão .js.

  4. No arquivo, escreva sua função JavaScript personalizada.

  5. No arquivo, digite este snippet de código:

     module.exports = { FUNCTION_NAME }
    

    Substitua FUNCTION_NAME pelo nome da sua função.

  6. Opcional: clique em Formatar.

O exemplo de código a seguir mostra uma função JavaScript personalizada chamada renderScript e armazenada no arquivo includes/functions.js. A função gera um script SQL:

  function renderScript(table, dimensions, metrics) {
    return `
        select
        ${dimensions.map(field => `${field} as ${field}`).join(",")},
        ${metrics.map(field => `sum(${field}) as ${field}`).join(",\n")}
        from ${table}
        group by ${dimensions.map((field, i) => `${i + 1}`).join(", ")}
      `;
  }

  module.exports = { renderScript };

A exemplo de código a seguir mostra o uso da função JavaScript renderScript personalizada em uma consulta de definição de tabela principal do Dataform:

  config {
      type: "table",
      tags: ["advanced", "hourly"],
      disabled: true
  }

  ${functions.renderScript(ref("source_table"),
                                ["country", "device_type"],
                                ["revenue", "pageviews", "sessions"]
                                )}

O exemplo de código a seguir mostra a consulta de definição da tabela principal do Dataform anterior compilada em SQL:

  select
    country as country,
    device_type as device_type,
    sum(revenue) as revenue,
    sum(pageviews) as pageviews,
    sum(sessions) as sessions

  from "dataform"."source_table"

  group by 1, 2

Referenciar um include em um arquivo SQLX

É possível referenciar qualquer função ou constante de inclusão em um arquivo SQLX. A sintaxe para referenciar inclusões depende do local do arquivo de inclusão. Um arquivo de inclusão de nível superior está localizado diretamente no diretório includes/. Um arquivo de inclusões aninhado está localizado em um subdiretório de includes/.

Referenciar uma inclusão de nível superior em um arquivo SQLX

  • Para referenciar uma função ou constante de inclusão de nível superior em uma consulta principal do Dataform, insira o nome do arquivo de definição de inclusão sem a extensão .js, seguido pelo nome do objeto exportado.

O exemplo de código a seguir faz referência à constante firstDate, definida no arquivo includes/constants.js, em um arquivo SQLX de definição de tabela:

  config {type: "table"}
  select * from source_table where date > ${constants.firstDate}

Referenciar um include aninhado em um arquivo SQLX

Para referenciar inclusões localizadas em subdiretórios de definitions, importe inclusões usando a função JavaScript require e um bloco js {}.

Para referenciar uma inclusão aninhada com a função JavaScript require, siga estas etapas:

  1. Acesse o espaço de trabalho de desenvolvimento.

  2. No painel Arquivos, expanda definitions/.

  3. Selecione um arquivo SQLX.

  4. No bloco config, insira o seguinte snippet de código:

     js {
       var { VARIABLE_NAME } = require("SUBDIRECTORY_INCLUDE");
     }
    

    Substitua:

    • VARIABLE_NAME: o nome da constante ou função que você quer importar
    • SUBDIRECTORY_INCLUDE: o caminho do arquivo includes aninhado
  5. Opcional: clique em Formatar.

O exemplo de código a seguir faz referência à constante firstDate, definida no arquivo aninhado includes/allConstants/constants.js, em um arquivo SQLX de definição de tabela:

  config {type: "table"}
  js {
    var { firstDate } = require("includes/allConstants/constants");
  }
  select * from source_table where date > ${firstDate}

Usar uma função de inclusão do JavaScript com a função ref do Dataform Core

Para usar uma função de inclusão do JavaScript com a função ref do Dataform Core, transmita ref como um argumento da função de inclusão do JavaScript em um arquivo SQLX.

O exemplo de código a seguir mostra o arquivo includes/script_builder.js com a função JavaScript renderScript que agrega métricas usando SUM e as agrupa por dimensão:

function renderScript(table, dimensions, metrics) {
  return `
      SELECT
      ${dimensions.map((field) => `${field} AS ${field}`).join(",\\n")},
      ${metrics.map((field) => `SUM(${field}) AS ${field}`).join(",\\n")}
      FROM ${table}
      GROUP BY ${dimensions.map((field, i) => `${i + 1}`).join(", ")}
    `;
}
module.exports = { renderScript };

O exemplo de código a seguir mostra a função renderScript JavaScript usada no arquivo definitions/stats_per_country_and_device.sqlx com a função ref principal do Dataform transmitida como um argumento:

${script_builder.renderScript(
  ref("source_table"),
  ["country", "device_type"],
  ["revenue", "pageviews", "sessions"])}

O exemplo de código a seguir mostra a consulta definitions/stats_per_country_and_device.sqlx compilada em SQL:

SELECT country AS country,
       device_type AS device_type,
       SUM(revenue) AS revenue,
       SUM(pageviews) AS pageviews,
       SUM(sessions) AS sessions
FROM my_schema.source_table
GROUP BY 1, 2

Para mais informações sobre a função ref principal do Dataform, consulte Dataform Core.

Reutilizar código em vários repositórios com pacotes

Pacotes são coleções de código JavaScript que podem ser importadas e usadas em vários repositórios do Dataform para simplificar o desenvolvimento do fluxo de trabalho.

Você pode criar seu próprio pacote personalizado no Dataform ou usar um dos pacotes de código aberto do Dataform, disponíveis na página de código aberto do Dataform no GitHub.

Para usar o conteúdo de um pacote no Dataform, é necessário instalar o pacote no repositório do Dataform e importá-lo para o arquivo JavaScript ou SQLX individual em que você quer usar o pacote. Para mais informações, consulte Instalar um pacote.

Para instalar um pacote NPM particular em um repositório do Dataform, é preciso autenticar o pacote.

Criar fluxos de trabalho exclusivamente com JavaScript

Nesta seção, mostramos como usar JavaScript para criar ações de fluxo de trabalho no Dataform. Talvez você queira usar JavaScript em vez do Dataform Core para criar elementos semelhantes repetidamente no seu fluxo de trabalho.

Como alternativa ao desenvolvimento de fluxos de trabalho em SQLX ou SQLX combinado com JavaScript, é possível criar ações de fluxo de trabalho em arquivos .js usando apenas JavaScript. É possível criar várias ações de fluxo de trabalho em um arquivo JavaScript com métodos globais do Dataform e código JavaScript ES5 arbitrário, como loops e constantes. Cada um dos métodos JavaScript globais do Dataform contém propriedades que podem ser usadas para configurar os objetos criados.

É possível criar as seguintes ações de fluxo de trabalho usando apenas JavaScript no Dataform:

  • Declarações de origem de dados
  • Tabelas
  • Declarações manuais
  • Operações SQL personalizadas

Com JavaScript, é possível criar ações semelhantes repetidamente no fluxo de trabalho. Por exemplo, é possível criar uma visualização de cada tabela no fluxo de trabalho com determinados IDs de usuário removidos.

O exemplo de código JavaScript a seguir permite criar uma visualização de cada tabela em que o valor do campo user_id não corresponde a um dos valores na lista blocked_user_ids:

  const tableNames = ["user_events", "user_settings", "user_logs"];

  tableNames.forEach(tableName => {
    publish(tableName + "_blocked_removed").query(
      ctx => `
        SELECT * FROM ${ctx.ref(tableName)}
        WHERE user_id NOT IN (
          SELECT user_id
          FROM ${ctx.ref("blocked_user_ids")}
        )`
    );
  });

Este exemplo de código cria três visualizações chamadas user_events_blocked_removed, user_settings_blocked_removed e user_logs_blocked_removed que não contêm nenhum dos IDs de usuário bloqueados.

É possível criar várias ações em um arquivo JavaScript com métodos globais do Dataform e código JavaScript ES5 arbitrário, como loops e constantes.

É possível definir as seguintes ações com JavaScript no Dataform:

Criar um arquivo JavaScript

Armazene arquivos JavaScript para definições e declarações de fonte de dados no diretório definitions/. Para criar um arquivo JavaScript no diretório definitions/, siga estas etapas:

  1. No painel Arquivos, ao lado de definitions/, clique em Mais.

  2. Selecione Criar arquivo.

  3. No painel Criar novo arquivo, faça o seguinte:

    1. No campo Adicionar um caminho de arquivo, depois de definitions/, insira o nome do arquivo seguido por .js. Por exemplo, definitions/definitions.js.

      Os nomes de arquivo só podem incluir números, letras, hifens e sublinhados.

    2. Selecione Criar arquivo.

Definir propriedades de ações de fluxo de trabalho com JavaScript

Use os seguintes métodos globais do Dataform para criar ações de fluxo de trabalho SQL com o Dataform:

  • declare. Usado para declarar uma fonte de dados.
  • publish. Usado para definir uma tabela.
  • assert. Usado para criar uma declaração.
  • operate. Usado para definir uma operação SQL personalizada.

Cada um dos métodos globais contém propriedades que podem ser usadas para configurar o objeto criado. Para mais informações sobre métodos globais e propriedades, consulte a referência principal do Dataform.

No método publish() que cria uma tabela, é possível definir as propriedades dela transmitindo-as como o segundo argumento do método.

Para transmitir propriedades da tabela como o segundo argumento de publish(), siga estas etapas:

  1. No espaço de trabalho de desenvolvimento, no painel Arquivos, abra definitions/.

  2. Selecione um arquivo JavaScript.

  3. No arquivo, adicione propriedades de tabela ao método publish() no seguinte formato:

     method("first_method_argument", {
       property1: "property1_value",
       property2: "property2_value",
       property3: "property3_value",
     });
    
  4. Opcional: clique em Formatar.

O exemplo de código a seguir mostra como definir propriedades para o método publish() transmitindo as propriedades como um segundo argumento do método:

  publish("table1", {
    type: "table",
    dependencies: ["other_table"],
    description: {
      "Value is 1"
    }
  }).query(ctx => "SELECT 1 AS test");

Incluir referências em um arquivo JavaScript

É possível referenciar qualquer função, macro ou constante de inclusão em um arquivo JavaScript. Para mais informações sobre inclusões no Dataform, consulte a seção Reutilizar código em um único repositório com inclusões deste documento.

A sintaxe para referenciar inclusões em um arquivo JavaScript depende da localização do arquivo de inclusão. O Dataform armazena esses arquivos no diretório "includes".

Os principais elementos de referência incluem

  • Para fazer referência a um arquivo de inclusões de nível superior, faça referência ao nome do arquivo ao declarar as variáveis.

O exemplo de código a seguir faz referência às variáveis serviceName e serviceId do arquivo includes/service.js:

  const {serviceName, serviceId} = service;

Referência a inclusões aninhadas

Para fazer referência a um arquivo de inclusões aninhado, insira o nome do arquivo na função require do JavaScript.

O exemplo de código a seguir faz referência às variáveis serviceName e serviceId do arquivo includes/allServices/service.js:

  const {serviceName, serviceId} = require("includes/allServices/service.js");

Usar funções de consulta do Dataform em métodos JavaScript

O Dataform oferece várias funções integradas que podem ser usadas em consultas, como ref e self. Para mais informações sobre as funções integradas do Dataform, consulte a referência da API do Dataform.

Para usar uma função de consulta integrada em um método JavaScript, siga estas etapas:

  1. No espaço de trabalho de desenvolvimento, no painel Arquivos, abra definitions/.

  2. Selecione um arquivo JavaScript.

  3. No arquivo, insira um método JavaScript global do Dataform.

  4. No método, insira um argumento ctx contextualizável.

  5. Opcional: se você estiver usando strings de modelo JavaScript, coloque o argumento contextualizável entre crases ``.

  6. No argumento contextable, insira a função de consulta com o parâmetro como um objeto de contexto.

  7. Opcional: clique em Formatar.

O exemplo de código a seguir mostra a função de consulta ref encapsulada em um argumento contextualizável do método de publicação:

  publish("example").query(ctx => `SELECT * FROM ${ctx.ref("other_table")}`);

Declarar uma fonte de dados de fluxo de trabalho com JavaScript

É possível declarar várias origens de dados em um arquivo de declaração JavaScript com o método JavaScript declare do Dataform. Para mais informações sobre o método "declare", consulte a referência principal do Dataform. Para mais informações sobre fontes de dados no Dataform, consulte Declarar uma fonte de dados.

Para declarar uma fonte de dados em um arquivo JavaScript, siga estas etapas:

  1. No espaço de trabalho de desenvolvimento, no painel Arquivos, abra definitions/.

  2. Selecione um arquivo JavaScript.

  3. No arquivo, digite este snippet de código:

     declare({
       database: "DATABASE_PROJECT_ID",
       schema: "BIGQUERY_SCHEMA",
       name: "RELATION_NAME",
     });
    

    Substitua:

    • DATABASE_PROJECT_ID: o ID do projeto que contém a fonte de dados
    • BIGQUERY_SCHEMA: o conjunto de dados do BigQuery em que a relação externa existe
    • RELATION_NAME: o nome da relação que você pode usar mais tarde para referenciar a fonte de dados no Dataform
  4. Para declarar outra fonte de dados no mesmo arquivo, adicione um bloco declare extra.

  5. Opcional: clique em Formatar.

Definir uma tabela com JavaScript

É possível criar uma tabela com o método publish do JavaScript do Dataform. Para mais informações sobre o método "publish", consulte a referência principal do Dataform.

É possível definir os seguintes tipos de tabela:

  • Tabela
  • Tabela incremental
  • Ver

Para mais informações sobre como definir tabelas no Dataform, consulte Criar tabelas.

Para definir uma tabela em um arquivo JavaScript, siga estas etapas:

  1. No espaço de trabalho de desenvolvimento, no painel Arquivos, abra definitions/.

  2. Selecione um arquivo JavaScript.

  3. No arquivo, digite este snippet de código:

     publish("TABLE_NAME").query(ctx => "SELECT_QUERY");
    

    Substitua:

    • TABLE_NAME: o nome da tabela
    • SELECT_QUERY: uma instrução SQL SELECT que define a tabela
  4. Para definir o tipo de tabela, adicionar dependências e uma descrição, use set object properties do método publish.

  5. Para definir outra tabela no mesmo arquivo, repita as etapas 3 e 4.

  6. Opcional: clique em Formatar.

Definir asserções manuais com JavaScript

É possível criar declarações SQL manuais em um arquivo JavaScript com o método assert do Dataform em JavaScript. Para mais informações sobre o método "assert", consulte a referência principal do Dataform.

Uma consulta SQL de asserção manual precisa retornar zero linhas. Se a consulta retornar linhas quando executada, a declaração vai falhar. É possível criar várias asserções em um arquivo JavaScript.

Para mais informações sobre declarações no Dataform, consulte Testar a qualidade dos dados.

Para criar uma asserção manual em um arquivo JavaScript, siga estas etapas:

  1. No espaço de trabalho de desenvolvimento, no painel Arquivos, abra definitions/.

  2. Selecione um arquivo JavaScript.

  3. No arquivo, digite este snippet de código:

     assert("ASSERTION_NAME").query(ctx => "CUSTOM_ASSERTION_QUERY");
    

    Substitua:

    • ASSERTION_NAME: o nome da sua declaração personalizada
    • CUSTOM_ASSERTION_QUERY: sua consulta de declaração SQL
  4. Para criar outra declaração no mesmo arquivo, repita a etapa 3.

  5. Opcional: clique em Formatar.

O exemplo de código a seguir mostra uma declaração JavaScript que afirma que nenhum valor em source_table é NULL:

  assert("assertion1").query(ctx => "SELECT * FROM source_table WHERE value IS NULL");

Definir operações SQL personalizadas com JavaScript

É possível definir operações SQL personalizadas em um arquivo JavaScript com o método Dataform operate JavaScript. Para mais informações sobre operações SQL personalizadas no Dataform, consulte Criar operações.

Para definir uma operação SQL personalizada com JavaScript, siga estas etapas:

  1. No espaço de trabalho de desenvolvimento, no painel Arquivos, abra definitions/.

  2. Selecione um arquivo JavaScript.

  3. No arquivo, digite este snippet de código:

     operate("OPERATION_NAME").queries(ctx => "CUSTOM_SQL_QUERY");
    

    Substitua:

    • OPERATION_NAME: o nome da operação personalizada
    • CUSTOM_SQL_QUERY: sua consulta SQL personalizada
  4. Para definir outra operação SQL personalizada no mesmo arquivo, repita a etapa 3.

  5. Opcional: clique em Formatar.

O exemplo de código a seguir mostra uma operação SQL personalizada em um arquivo JavaScript que insere uma única linha nova em some_table e define test_column da nova linha como 2:

  operate("operation1").queries("INSERT INTO some_table (test_column) VALUES (2)");

A seguir