Use JavaScript no Dataform

Este documento ajuda a compreender como pode 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.

O Dataform core permite-lhe criar ações de fluxo de trabalho com SQLX e JavaScript. Embora seja opcional, pode usar JavaScript juntamente com SQLX para criar elementos semelhantes repetidamente no seu fluxo de trabalho. Por exemplo, com JavaScript, pode criar uma vista de cada tabela no seu fluxo de trabalho com determinados IDs de utilizadores removidos. Também pode desenvolver ações de fluxo de trabalho exclusivamente com JavaScript.

Antes de começar

  1. Na Google Cloud consola, aceda à página Dataform.

    Aceder ao Dataform

  2. Selecione ou crie um repositório.

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

Além disso, tem de conhecer a sintaxe JavaScript e os seguintes conceitos de JavaScript:

  • Variáveis
  • Matrizes
  • Declarações condicionais
  • Para repetições
  • Maps
  • Funções
  • Objetos
  • Exportação e importação de módulos

Funções necessárias

Para receber as autorizações de que precisa para desenvolver um fluxo de trabalho com JavaScript e reutilizar código com inclusões de JavaScript, peça ao seu administrador para lhe conceder a função do editor do Dataform (roles/dataform.editor) IAM em espaços de trabalho. Para mais informações sobre a atribuição de funções, consulte o artigo Faça a gestão do acesso a projetos, pastas e organizações.

Também pode conseguir as autorizações necessárias através de funções personalizadas ou outras funções predefinidas.

Adicione código JavaScript a um ficheiro SQLX

Pode adicionar código JavaScript a um ficheiro SQLX de duas formas: em linha ou num bloco JavaScript.

Pode usar um bloco JavaScript para definir funções ou constantes num ficheiro SQLX. Pode usar JavaScript inline para modificar dinamicamente uma consulta SQLX ou SQL.

O seguinte exemplo de código mostra a função JavaScript incorporada do núcleo do Dataform adicionada inline ao bloco post_operations num ficheiro SQLX:self

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 seguinte mostra uma constante definida num bloco JavaScript e usada inline numa consulta num ficheiro SQLX:

js {
  const columnName = "foo";
}

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

Reutilize código num único ficheiro SQLX com encapsulamento de JavaScript

Pode reutilizar o código JavaScript para simplificar o desenvolvimento no Dataform. Para reutilizar constantes e funções JavaScript num único ficheiro SQLX, pode encapsulá-las num bloco JavaScript. Para reutilizar código JavaScript num único repositório do Dataform, pode criar inclusões. Para reutilizar código JavaScript em vários repositórios do Dataform, pode criar ou importar um pacote.

Para criar partes repetitivas de código SQL que pode reutilizar num único ficheiro SQLX, pode encapsular funções e constantes num bloco JavaScript. Só pode reutilizar código definido num bloco de JavaScript no ficheiro SQLX onde o bloco está definido. Para mais informações, consulte o Dataform core.

O exemplo de código seguinte mostra uma constante e uma função definidas num bloco de JavaScript e usadas inline numa consulta num ficheiro SQLX:

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

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

Reutilize código num único repositório com inclusões

As inclusões são constantes ou funções JavaScript globais para o seu repositório. Define as inclusões no diretório includes do seu repositório. Em seguida, pode reutilizá-los no seu repositório em ficheiros JavaScript e SQLX.

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

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

O exemplo de código seguinte mostra a constante launch_date referenciada numa consulta de definição de tabela num ficheiro SQLX:

config {type: "table"}

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

Crie um ficheiro JavaScript para inclusões

Para criar um novo ficheiro JavaScript no diretório includes/, siga estes passos:

  1. No painel Ficheiros, junto a includes/, clique em Mais.

  2. Clique em Criar ficheiro.

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

    1. No campo Adicionar um caminho do ficheiro, após includes/, introduza o nome do ficheiro seguido de .js. Por exemplo, includes/constants.js.

      Os nomes de ficheiros só podem incluir números, letras, hífenes e sublinhados.

    2. Clique em Criar ficheiro.

Crie uma constante de JavaScript

Para criar uma constante que pode reutilizar no seu projeto, siga estes passos:

  1. Aceda ao seu espaço de trabalho de desenvolvimento.

  2. No painel Ficheiros, expanda includes/.

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

  4. No ficheiro, introduza o seguinte fragmento do código:

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

    Substitua o seguinte:

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

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

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

O exemplo de código seguinte faz referência à constante PROJECT_ID numa consulta de definição de tabela num ficheiro SQLX:

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

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

Crie uma função de JavaScript personalizada

Para criar uma função de JavaScript personalizada que pode reutilizar no seu projeto, siga estes passos:

  1. Aceda ao seu espaço de trabalho de desenvolvimento.

  2. No painel Ficheiros, expanda includes/.

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

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

  5. No ficheiro, introduza o seguinte fragmento do código:

     module.exports = { FUNCTION_NAME }
    

    Substitua FUNCTION_NAME pelo nome da sua função.

  6. Opcional: clique em Formatar.

O seguinte exemplo de código mostra uma função JavaScript personalizada que é chamada renderScript e armazenada no ficheiro 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 seguinte mostra a utilização da função JavaScript renderScript personalizada numa 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 seguinte exemplo de código 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

Referencie uma inclusão num ficheiro SQLX

Pode referenciar qualquer função de inclusão ou constante num ficheiro SQLX. A sintaxe para referenciar includes depende da localização do ficheiro include. Um ficheiro de inclusão de nível superior está localizado diretamente no diretório includes/. Um ficheiro de inclusões aninhado está localizado num subdiretório de includes/.

Referencie uma inclusão de nível superior num ficheiro SQLX

  • Para fazer referência a uma função de inclusão ou a uma constante de nível superior numa consulta do Dataform Core, introduza o nome do ficheiro de definição de inclusão sem a extensão .js, seguido do nome do objeto exportado.

O exemplo de código seguinte faz referência à constante firstDate, definida no ficheiro includes/constants.js, num ficheiro SQLX de definição de tabela:

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

Referencie uma inclusão aninhada num ficheiro SQLX

Para fazer referência a inclusões localizadas em subdiretórios de definitions, importe inclusões através da função require JavaScript e de um bloco js {}.

Para fazer referência a uma inclusão aninhada com a função JavaScript require, siga estes passos:

  1. Aceda ao seu espaço de trabalho de desenvolvimento.

  2. No painel Ficheiros, expanda definitions/.

  3. Selecione um ficheiro SQLX.

  4. No bloco config, introduza o seguinte fragmento do código:

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

    Substitua o seguinte:

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

O exemplo de código seguinte faz referência à constante firstDate, definida no ficheiro includes/allConstants/constants.js aninhado, num ficheiro SQLX de definição de tabela:

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

Use 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 principal do Dataform, tem de transmitir ref como um argumento da função de inclusão do JavaScript num ficheiro SQLX.

O exemplo de código seguinte mostra o ficheiro includes/script_builder.js com a função JavaScript renderScript que agrega métricas através de 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 seguinte mostra a função JavaScript renderScript usada no ficheiro definitions/stats_per_country_and_device.sqlx com a função ref do Dataform core transmitida como argumento:

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

O seguinte exemplo de código 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 core do Dataform, consulte o artigo Dataform core.

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

Os pacotes são coleções de código JavaScript que pode importar e usar em vários repositórios do Dataform para simplificar o desenvolvimento do fluxo de trabalho.

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

Para poder usar o conteúdo de um pacote no Dataform, tem de instalar o pacote no seu repositório do Dataform e, em seguida, importá-lo para o ficheiro JavaScript ou SQLX individual no qual quer usar o pacote. Para mais informações, consulte o artigo Instale um pacote.

Para poder instalar um pacote NPM privado num repositório do Dataform, tem de autenticar o pacote.

Crie fluxos de trabalho exclusivamente com JavaScript

Esta secção mostra como usar JavaScript para criar ações de fluxo de trabalho no Dataform. É recomendável usar JavaScript em vez do Dataform core para criar elementos semelhantes repetidamente no seu fluxo de trabalho.

Em alternativa ao desenvolvimento de fluxos de trabalho em SQLX ou SQLX combinado com JavaScript, pode criar ações de fluxo de trabalho em ficheiros .js usando apenas JavaScript. Pode criar várias ações de fluxo de trabalho num ficheiro JavaScript com métodos globais do Dataform e código JavaScript ES5 arbitrário, como ciclos e constantes. Cada um dos métodos JavaScript globais do Dataform contém propriedades que pode usar para configurar os objetos criados.

Pode criar as seguintes ações de fluxo de trabalho usando apenas JavaScript no Dataform:

  • Declarações de origens de dados
  • Tabelas
  • Afirmações manuais
  • Operações de SQL personalizado

Com o JavaScript, pode criar ações semelhantes repetidamente no seu fluxo de trabalho. Por exemplo, pode criar uma vista de cada tabela no seu fluxo de trabalho com determinados IDs de utilizadores removidos.

O exemplo de código JavaScript seguinte permite-lhe criar uma vista 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 de propriedade denominadas user_events_blocked_removed, user_settings_blocked_removed e user_logs_blocked_removed que não contêm nenhum dos IDs de utilizadores bloqueados.

Pode criar várias ações num ficheiro JavaScript com métodos globais do Dataform e código JavaScript ES5 arbitrário, como ciclos e constantes.

Pode definir as seguintes ações com JavaScript no Dataform:

Crie um ficheiro JavaScript

Armazene ficheiros JavaScript para definições e declarações de origens de dados no diretório definitions/. Para criar um novo ficheiro JavaScript no diretório definitions/, siga estes passos:

  1. No painel Ficheiros, junto a definitions/, clique em Mais.

  2. Clique em Criar ficheiro.

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

    1. No campo Adicionar um caminho de ficheiro, após definitions/, introduza o nome do ficheiro seguido de .js. Por exemplo, definitions/definitions.js.

      Os nomes de ficheiros só podem incluir números, letras, hífenes e sublinhados.

    2. Clique em Criar ficheiro.

Defina propriedades de ações do fluxo de trabalho com JavaScript

Pode 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 origem de dados.
  • publish. Usado para definir uma tabela.
  • assert. Usado para criar uma afirmação.
  • operate. Usado para definir uma operação SQL personalizada.

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

No método publish() que cria uma tabela, pode 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 estes passos:

  1. No espaço de trabalho de desenvolvimento, no painel Ficheiros, expanda definitions/.

  2. Selecione um ficheiro JavaScript.

  3. No ficheiro, adicione propriedades da 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 seguinte exemplo de código mostra como definir propriedades para o método publish() ao transmitir 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 num ficheiro JavaScript

Pode fazer referência a qualquer função, macro ou constante de inclusão num ficheiro JavaScript. Para mais informações sobre inclusões no Dataform, consulte a secção Reutilize código num único repositório com inclusões deste documento.

A sintaxe para referenciar inclusões num ficheiro JavaScript depende da localização do ficheiro de inclusão. O Dataform armazena esses ficheiros no diretório includes.

Inclui referências de nível superior

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

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

  const {serviceName, serviceId} = service;

Referência inclui aninhada

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

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

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

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

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

Para usar uma função de consulta integrada num método JavaScript, siga estes passos:

  1. No espaço de trabalho de desenvolvimento, no painel Ficheiros, expanda definitions/.

  2. Selecione um ficheiro JavaScript.

  3. No ficheiro, introduza um método JavaScript do Dataform global.

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

  5. Opcional: se estiver a usar strings de modelos JavaScript, coloque o argumento contextable entre acentos graves ``.

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

  7. Opcional: clique em Formatar.

O exemplo de código seguinte mostra a função de consulta ref incluída num argumento contextualizável do método publish:

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

Declare uma origem de dados do fluxo de trabalho com JavaScript

Pode declarar várias origens de dados num ficheiro 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 as origens de dados no Dataform, consulte o artigo Declare uma origem de dados.

Para declarar uma origem de dados num ficheiro JavaScript, siga estes passos:

  1. No espaço de trabalho de desenvolvimento, no painel Ficheiros, expanda definitions/.

  2. Selecione um ficheiro JavaScript.

  3. No ficheiro, introduza o seguinte fragmento do código:

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

    Substitua o seguinte:

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

  5. Opcional: clique em Formatar.

Defina uma tabela com JavaScript

Pode criar uma tabela com o método publish JavaScript do Dataform. Para mais informações sobre o método de publicação, consulte a referência principal do Dataform.

Pode definir os seguintes tipos de tabelas:

  • Tabela
  • Tabela incremental
  • Ver

Para mais informações sobre a definição de tabelas no Dataform, consulte o artigo Crie tabelas.

Para definir uma tabela num ficheiro JavaScript, siga estes passos:

  1. No espaço de trabalho de desenvolvimento, no painel Ficheiros, expanda definitions/.

  2. Selecione um ficheiro JavaScript.

  3. No ficheiro, introduza o seguinte fragmento do código:

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

    Substitua o seguinte:

    • TABLE_NAME: o nome da tabela
    • SELECT_QUERY: uma declaração SQL SELECT que define a tabela
  4. Para definir o tipo de tabela, adicionar dependências de tabelas e adicionar a descrição da tabela, defina as propriedades do objeto do método publish.

  5. Para definir outra tabela no mesmo ficheiro, repita os passos 3 e 4.

  6. Opcional: clique em Formatar.

Defina asserções manuais com JavaScript

Pode criar afirmações SQL manuais num ficheiro JavaScript com o método JavaScript assert do Dataform. Para mais informações sobre o método assert, consulte a referência principal do Dataform.

Uma consulta SQL de afirmação manual tem de devolver zero linhas. Se a consulta devolver linhas quando for executada, a asserção falha. Pode criar várias afirmações num ficheiro JavaScript.

Para mais informações sobre as afirmações no Dataform, consulte o artigo Teste a qualidade dos dados.

Para criar uma afirmação manual num ficheiro JavaScript, siga estes passos:

  1. No espaço de trabalho de desenvolvimento, no painel Ficheiros, expanda definitions/.

  2. Selecione um ficheiro JavaScript.

  3. No ficheiro, introduza o seguinte fragmento do código:

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

    Substitua o seguinte:

    • ASSERTION_NAME: o nome da sua afirmação personalizada
    • CUSTOM_ASSERTION_QUERY: a sua consulta de validação SQL
  4. Para criar outra afirmação no mesmo ficheiro, repita o passo 3.

  5. Opcional: clique em Formatar.

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

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

Defina operações SQL personalizadas com JavaScript

Pode definir operações SQL personalizadas num ficheiro JavaScript com o método JavaScript Dataform operate. Para mais informações sobre as operações SQL personalizadas no Dataform, consulte o artigo Crie operações.

Para definir uma operação SQL personalizada com JavaScript, siga estes passos:

  1. No espaço de trabalho de desenvolvimento, no painel Ficheiros, expanda definitions/.

  2. Selecione um ficheiro JavaScript.

  3. No ficheiro, introduza o seguinte fragmento do código:

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

    Substitua o seguinte:

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

  5. Opcional: clique em Formatar.

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

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

O que se segue?