Usar JavaScript no Dataform

Este documento ajuda você a entender como usar o 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 o código no Dataform.

O núcleo do Dataform permite criar ações de fluxo de trabalho com SQLX e JavaScript. Embora opcional, use o JavaScript com o 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 Console do Google Cloud, acesse a página Dataform.

    Acessar 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 do JavaScript:

  • 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 o código com JavaScript, peça ao administrador que conceda a você o papel do IAM Editor de formulário de dados (roles/dataform.editor) nos 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 o JavaScript inline para modificar dinamicamente uma consulta SQLX ou SQL.

O exemplo de código abaixo mostra a função JavaScript incorporada 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

Você pode 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 do 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 é definido. Para mais informações, consulte Núcleo do Dataform.

O exemplo de código abaixo 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 includes

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

O exemplo de código abaixo 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 novo arquivo JavaScript no diretório includes/, siga estas etapas:

  1. No painel Files, ao lado de includes/, clique em More.

  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/, digite o nome do arquivo seguido de .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 do JavaScript

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

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

  2. No painel Files, abra 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 constante
  5. Opcional: clique em Formato.

O exemplo de código abaixo 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 abaixo 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 anterior de definição de tabela principal do Dataform 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 possa ser reutilizada em todo o projeto, siga estas etapas:

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

  2. No painel Files, abra 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 Formato.

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 };

O exemplo de código abaixo 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 de 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

Fazer referência a um arquivo de inclusão em um arquivo SQLX

É possível fazer referência a qualquer função ou constante de inclusão em um arquivo SQLX. A sintaxe para fazer referência a inclui depende do local do arquivo de inclusão. Um arquivo de inclusão de nível superior fica localizado diretamente no diretório includes/. Um arquivo de inclusão aninhado está localizado em um subdiretório de includes/.

Fazer referência a um include de nível superior em um arquivo SQLX

  • Para fazer referência a uma função ou constante de inclusão de nível superior em uma consulta do núcleo 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}

Fazer referência a um include aninhado em um arquivo SQLX

Para fazer referência a includes localizados em subdiretórios de definitions, importe includes usando a função require do JavaScript e um bloco js {}.

Para fazer referência a um include aninhado com a função JavaScript require, siga estas etapas:

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

  2. No painel Files, abra 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 Formato.

O exemplo de código abaixo faz referência à constante firstDate, definida no arquivo includes/allConstants/constants.js aninhado, 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 núcleo do Dataform

Para usar uma função de inclusão JavaScript com a função ref do núcleo do Dataform, é necessário transmitir ref como um argumento da função de inclusão 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 JavaScript renderScript usada no arquivo definitions/stats_per_country_and_device.sqlx com a função ref do núcleo 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 para 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 do núcleo do Dataform, consulte Núcleo do Dataform.

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

Os pacotes são coleções de código JavaScript que podem ser importados e usados em vários repositórios do Dataform para agilizar 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 do Dataform de código aberto do GitHub.

Para conferir um exemplo de uso de um pacote de código aberto no Dataform, consulte Usar dimensões que mudam lentamente no Dataform.

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

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

Criar fluxos de trabalho exclusivamente com JavaScript

Esta seção mostra como usar o JavaScript para criar ações de fluxo de trabalho no Dataform. Talvez seja melhor usar JavaScript em vez do núcleo do Dataform para criar elementos semelhantes repetidamente no seu fluxo de trabalho.

Como alternativa ao desenvolvimento de fluxos de trabalho no 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
  • Afirmações manuais
  • Operações SQL personalizadas

Com o JavaScript, é possível criar ações semelhantes repetidamente no seu fluxo de trabalho. Por exemplo, é possível criar uma visualização de cada tabela no seu 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 origem de dados no diretório definitions/. Para criar um novo arquivo JavaScript no diretório definitions/, siga estas etapas:

  1. No painel Files, ao lado de definitions/, clique em More.

  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/, digite o nome do arquivo seguido de .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ção do fluxo de trabalho com JavaScript

É possível usar 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 as respectivas propriedades, consulte a referência do núcleo do Dataform.

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

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

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

  2. Selecione um arquivo JavaScript.

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

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

O exemplo de código abaixo 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");

Referências incluídas em um arquivo JavaScript

É possível fazer referência a 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 fazer referência a inclui em um arquivo JavaScript depende do local do arquivo de inclusão. O Dataform armazena esses arquivos no diretório includes.

Inclui nível superior de referência

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

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

  const {serviceName, serviceId} = service;

Inclui referências aninhadas

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

O exemplo de código abaixo 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, abra definitions/ no painel Files.

  2. Selecione um arquivo JavaScript.

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

  4. No método, insira um argumento ctx com contexto.

  5. Opcional: se você estiver usando strings de modelo JavaScript, coloque o argumento com contexto em chaves inglesas ``.

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

  7. Opcional: clique em Formato.

O exemplo de código a seguir mostra a função de consulta ref inserida em um argumento com contexto 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 de declaração de JavaScript do Dataform. Para mais informações sobre o método de declaração, consulte a referência do núcleo do Dataform. Para mais informações sobre as 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, abra definitions/ no painel Files.

  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 pode ser usado mais tarde para fazer referência à fonte de dados no Dataform
  4. Para declarar outra fonte de dados no mesmo arquivo, adicione um bloco declare extra ao arquivo.

  5. Opcional: clique em Formato.

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 de publicação, consulte a referência do núcleo 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 uma tabela.

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

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

  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 descrições, defina propriedades do objeto do método publish.

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

  6. Opcional: clique em Formato.

Definir declarações manuais com JavaScript

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

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

Para mais informações sobre as declarações no Dataform, consulte Testar tabelas com declarações.

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

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

  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 Formato.

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 de operação JavaScript do Dataform. Para mais informações sobre operações SQL personalizadas no Dataform, consulte Adicionar operações SQL personalizadas.

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

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

  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 Formato.

O exemplo de código abaixo 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