Usa JavaScript en Dataform

Este documento te ayuda a comprender cómo puedes usar JavaScript para desarrollar flujos de trabajo en Dataform. En este documento, también se muestra cómo usar JavaScript para crear acciones de flujo de trabajo y cómo crear inclusiones de JavaScript para volver a usar el código en Dataform.

Dataform core te permite crear acciones de flujo de trabajo con SQLX y JavaScript. Si bien es opcional, usar JavaScript junto con SQLX para crear elementos similares de forma reiterada en tu flujo de trabajo Por ejemplo, con JavaScript, puedes crear una vista de cada tabla de tu flujo de trabajo con ciertos IDs de usuario quitados. También puedes desarrollar acciones de flujo de trabajo exclusivamente con JavaScript.

Antes de comenzar

  1. En la consola de Google Cloud, ve a la página Dataform.

    Ir a Dataform

  2. Selecciona o crea un repositorio.

  3. Selecciona o crea un lugar de trabajo de desarrollo.

Además, debes estar familiarizado con la sintaxis de JavaScript y los siguientes conceptos de JavaScript:

  • Variables
  • Arrays
  • Sentencias condicionales
  • Bucles for
  • Maps
  • Funciones
  • Objetos
  • Cómo exportar e importar módulos

Roles obligatorios

Para obtener los permisos que necesitas para desarrollar un flujo de trabajo con JavaScript y reutilizar código con incorporaciones de JavaScript, pídele a tu administrador que te otorgue el rol de IAM de Editor de Dataform (roles/dataform.editor) en los espacios de trabajo. Para obtener más información sobre cómo otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.

También puedes obtener los permisos necesarios mediante roles personalizados o cualquier otro rol predefinido.

Agrega código JavaScript a un archivo SQLX

Puedes agregar código JavaScript a un archivo SQLX de dos maneras: intercalado o dentro de un bloque de JavaScript.

Puedes usar un bloque de JavaScript para definir funciones o constantes en un archivo SQLX. Puedes usar JavaScript intercalado para modificar de forma dinámica una consulta SQLX o SQL.

En la siguiente muestra de código, se muestra la función de JavaScript integrada en el núcleo de self de Dataform que se agregó intercalada al bloque post_operations en un archivo SQLX:

config {type: "table"}

SELECT * FROM ...

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

En la siguiente muestra de código, se muestra una constante definida en un bloque de JavaScript y que se usa intercalada dentro de una consulta en un archivo SQLX:

js {
  const columnName = "foo";
}

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

Cómo volver a usar el código en un solo archivo SQLX con encapsulamiento de JavaScript

Puedes reutilizar el código de JavaScript para optimizar el desarrollo en Dataform. Para volver a usar constantes y funciones de JavaScript en un solo archivo SQLX, puedes encapsularlas en un bloque de JavaScript. Para volver a usar el código JavaScript en un solo repositorio de Dataform, puedes crear inclusiones. Para reutilizar el código de JavaScript en varios repositorios de Dataform, puedes crear o importar un paquete.

Para crear partes repetitivas de código SQL que puedas volver a usar en un solo archivo SQLX, puedes encapsular funciones y constantes en un bloque de JavaScript. Puedes volver a usar el código definido en un bloque de JavaScript solo dentro del archivo SQLX en el que se define el bloque. Para obtener más información, consulta Dataform Core.

En el siguiente ejemplo de código, se muestra una constante y una función definidas en un bloque de JavaScript y que se usan intercaladas dentro de una consulta en un archivo SQLX:

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

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

Cómo volver a usar el código en un solo repositorio con inclusiones

Las inclusiones son constantes o funciones de JavaScript globales para tu repositorio. Puedes definir las inclusiones en el directorio includes de tu repositorio. Luego, puedes volver a usarlos en tu repositorio en archivos JavaScript y SQLX.

En la siguiente muestra de código, se muestra la definición de la constante launch_date en el archivo includes/constants.js:

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

En la siguiente muestra de código, se muestra la constante launch_date a la que se hace referencia en una consulta de definición de tabla en un archivo SQLX:

config {type: "table"}

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

Crea un archivo JavaScript para las inclusiones

Para crear un archivo JavaScript nuevo en el directorio includes/, sigue estos pasos:

  1. En el panel Archivos, junto a includes/, haz clic en Más.

  2. Haz clic en Crear archivo.

  3. En el panel Crear un archivo nuevo, haz lo siguiente:

    1. En el campo Agregar una ruta de archivo, después de includes/, ingresa el nombre del archivo seguido de .js. Por ejemplo, includes/constants.js.

      Los nombres de archivo solo pueden incluir números, letras, guiones y guiones bajos.

    2. Haz clic en Crear archivo.

Crea una constante de JavaScript

Para crear una constante que puedas volver a usar en tu proyecto, sigue estos pasos:

  1. Ve a tu lugar de trabajo de desarrollo.

  2. En el panel Archivos, expande includes/.

  3. Crea o selecciona un archivo JavaScript con la extensión .js.

  4. En el archivo, ingresa el siguiente fragmento de código:

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

    Reemplaza lo siguiente:

    • CONSTANT_NAME: Es el nombre de tu constante.
    • CONSTANT_VALUE: Es el valor de tu constante.
  5. Opcional: Haz clic en Formato.

En la siguiente muestra de código, se define la constante PROJECT_ID en el archivo includes/constants.js:

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

En la siguiente muestra de código, se hace referencia a la constante PROJECT_ID en una consulta de definición de tabla en un archivo SQLX:

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

En la siguiente muestra de código, se muestra la consulta de definición de la tabla principal de Dataform anterior compilada en SQL:

  SELECT * FROM my_project_name.my_schema_name.my_table_name

Crea una función de JavaScript personalizada

Para crear una función personalizada de JavaScript que puedas volver a usar en tu proyecto, sigue estos pasos:

  1. Ve a tu lugar de trabajo de desarrollo.

  2. En el panel Archivos, expande includes/.

  3. Crea o selecciona un archivo JavaScript con la extensión .js.

  4. En el archivo, escribe tu función de JavaScript personalizada.

  5. En el archivo, ingresa el siguiente fragmento de código:

     module.exports = { FUNCTION_NAME }
    

    Reemplaza FUNCTION_NAME por el nombre de tu función.

  6. Opcional: Haz clic en Formato.

En la siguiente muestra de código, se muestra una función personalizada de JavaScript que se llama renderScript y se almacena en el archivo includes/functions.js. La función genera una secuencia de comandos de 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 };

En el siguiente ejemplo de código, se muestra el uso de la función personalizada renderScript de JavaScript en una consulta de definición de tabla principal de Dataform:

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

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

En la siguiente muestra de código, se muestra la consulta de definición de la tabla principal de Dataform compilada en 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

Cómo hacer referencia a una inclusión en un archivo SQLX

Puedes hacer referencia a cualquier función o constante de inclusión dentro de un archivo SQLX. La sintaxis para incluir referencias depende de la ubicación del archivo de inclusión. Un archivo de inclusión de nivel superior se encuentra directamente en el directorio includes/. Un archivo de inclusión anidado se encuentra en un subdirectorio de includes/.

Cómo hacer referencia a una inclusión de nivel superior en un archivo SQLX

  • Para hacer referencia a una función o constante de inclusión de nivel superior en una consulta principal de Dataform, ingresa el nombre de archivo de la definición de inclusión sin la extensión .js, seguida del nombre del objeto exportado.

En la siguiente muestra de código, se hace referencia a la constante firstDate, definida en el archivo includes/constants.js, en un archivo SQLX de definición de tablas:

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

Cómo hacer referencia a una inclusión anidada en un archivo SQLX

Para hacer referencia a las incorporaciones ubicadas en subdirectorios de definitions, importa las incorporaciones con la función require de JavaScript y un bloque js {}.

Para hacer referencia a una inclusión anidada con la función require de JavaScript, sigue estos pasos:

  1. Ve a tu lugar de trabajo de desarrollo.

  2. En el panel Archivos, expande definitions/.

  3. Selecciona un archivo SQLX.

  4. En el bloque config, ingresa el siguiente fragmento de código:

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

    Reemplaza lo siguiente:

    • VARIABLE_NAME: Es el nombre de la constante o función que deseas importar.
    • SUBDIRECTORY_INCLUDE: Es la ruta de acceso del archivo includes anidado.
  5. Opcional: Haz clic en Formato.

En la siguiente muestra de código, se hace referencia a la constante firstDate, definida en el archivo includes/allConstants/constants.js anidado, en un archivo SQLX de definición de tablas:

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

Usa una función de inclusión de JavaScript con la función ref principal de Dataform

Para usar una función de inclusión de JavaScript con la función ref principal de Dataform, debes pasar ref como argumento de la función de inclusión de JavaScript dentro de un archivo SQLX.

En la siguiente muestra de código, se muestra el archivo includes/script_builder.js con la función renderScript de JavaScript que agrega métricas con SUM y las agrupa por dimensión:

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

En la siguiente muestra de código, se muestra la función renderScript de JavaScript que se usa en el archivo definitions/stats_per_country_and_device.sqlx con la función ref principal de Dataform que se pasa como argumento:

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

En la siguiente muestra de código, se muestra la consulta definitions/stats_per_country_and_device.sqlx compilada a 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 obtener más información sobre la función ref del núcleo de Dataform, consulta Núcleo de Dataform.

Cómo volver a usar el código en varios repositorios con paquetes

Los paquetes son colecciones de código JavaScript que puedes importar y usar en varios repositorios de Dataform para optimizar el desarrollo de flujos de trabajo.

Puedes crear tu propio paquete personalizado en Dataform o usar uno de los paquetes de Dataform de código abierto, disponibles en la página de Dataform de código abierto de GitHub.

Para ver un ejemplo del uso de un paquete de código abierto en Dataform, consulta Cómo usar dimensiones que cambian con lentitud en Dataform.

Para poder usar el contenido de un paquete en Dataform, debes instalarlo en tu repositorio de Dataform y, luego, importarlo al archivo JavaScript o SQLX individual en el que deseas usarlo. Para obtener más información, consulta Cómo instalar un paquete.

Para poder instalar un paquete de NPM privado en un repositorio de Dataform, debes autenticarlo.

Crea flujos de trabajo exclusivamente con JavaScript

En esta sección, se muestra cómo usar JavaScript para crear acciones de flujo de trabajo en Dataform. Te recomendamos que uses JavaScript en lugar del núcleo de Dataform para crear elementos similares de forma reiterada en tu flujo de trabajo.

Como alternativa a desarrollar flujos de trabajo en SQLX o SQLX combinado con JavaScript, puedes crear acciones de flujo de trabajo en archivos .js con solo JavaScript. Puedes crear varias acciones de flujo de trabajo dentro de un archivo JavaScript con métodos globales de Dataform y código arbitrario de JavaScript ES5, como bucles y constantes. Cada uno de los métodos de JavaScript globales de Dataform contiene propiedades que puedes usar para configurar los objetos creados.

Puedes crear las siguientes acciones de flujo de trabajo con solo JavaScript en Dataform:

  • Declaraciones de fuentes de datos
  • Tablas
  • Aserciones manuales
  • Operaciones de SQL personalizadas

Con JavaScript, puedes crear acciones similares de forma reiterada en tu flujo de trabajo. Por ejemplo, puedes crear una vista de cada tabla de tu flujo de trabajo con ciertos IDs de usuario quitados.

En la siguiente muestra de código de JavaScript, puedes crear una vista de cada tabla en la que el valor del campo user_id no corresponda a uno de los valores de la 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")}
        )`
    );
  });

En esta muestra de código, se crean tres vistas llamadas user_events_blocked_removed, user_settings_blocked_removed y user_logs_blocked_removed que no contienen ninguno de los IDs de usuario bloqueados.

Puedes crear varias acciones dentro de un archivo JavaScript con métodos globales de Dataform y código arbitrario de JavaScript ES5, como loops y constantes.

Puedes definir las siguientes acciones con JavaScript en Dataform:

Crea un archivo JavaScript

Almacena los archivos JavaScript para las definiciones y las declaraciones de fuentes de datos en el directorio definitions/. Para crear un archivo JavaScript nuevo en el directorio definitions/, sigue estos pasos:

  1. En el panel Archivos, junto a definitions/, haz clic en Más.

  2. Haz clic en Crear archivo.

  3. En el panel Crear un archivo nuevo, haz lo siguiente:

    1. En el campo Agregar una ruta de archivo, después de definitions/, ingresa el nombre del archivo seguido de .js. Por ejemplo, definitions/definitions.js

      Los nombres de archivo solo pueden incluir números, letras, guiones y guiones bajos.

    2. Haz clic en Crear archivo.

Cómo establecer propiedades de acción de flujo de trabajo con JavaScript

Puedes usar los siguientes métodos globales de Dataform para crear acciones de flujo de trabajo de SQL con Dataform:

  • declare: Se usa para declarar una fuente de datos.
  • publish: Se usa para definir una tabla.
  • assert: Se usa para crear una aserción.
  • operate: Se usa para definir una operación de SQL personalizada.

Cada uno de los métodos globales contiene propiedades que puedes usar para configurar el objeto creado. Para obtener más información sobre los métodos globales y sus propiedades, consulta la referencia principal de Dataform.

En el método publish() que crea una tabla, puedes configurar sus propiedades pasándolas como segundo argumento del método.

Para pasar propiedades de tabla como segundo argumento de publish(), sigue estos pasos:

  1. En el panel Files de tu lugar de trabajo de desarrollo, expande definitions/.

  2. Selecciona un archivo JavaScript.

  3. En el archivo, agrega propiedades de tabla al método publish() en el siguiente formato:

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

En la siguiente muestra de código, se muestra cómo configurar propiedades en el método publish() pasando las propiedades como segundo argumento del método:

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

Referencia de inclusión en un archivo JavaScript

Puedes hacer referencia a cualquier función, macro o constante de inclusión dentro de un archivo JavaScript. Para obtener más información sobre las inclusiones en Dataform, consulta la sección Cómo volver a usar código en un solo repositorio con inclusiones de este documento.

La sintaxis para hacer referencia a las inclusiones dentro de un archivo JavaScript depende de la ubicación del archivo de inclusión. Dataform almacena esos archivos en el directorio de inclusiones.

El nivel superior de referencia incluye

  • Para hacer referencia a un archivo de inclusión de nivel superior, haz referencia al nombre del archivo cuando declares tus variables.

En la siguiente muestra de código, se hace referencia a las variables serviceName y serviceId del archivo includes/service.js:

  const {serviceName, serviceId} = service;

Incluye referencias anidadas

Para hacer referencia a un archivo de inclusión anidado, ingresa el nombre del archivo en la función require de JavaScript.

En la siguiente muestra de código, se hace referencia a las variables serviceName y serviceId del archivo includes/allServices/service.js:

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

Usa funciones de consulta de Dataform en métodos de JavaScript

Dataform proporciona una serie de funciones integradas que puedes usar dentro de las consultas, como ref y self. Para obtener más información sobre las funciones integradas de Dataform, consulta la referencia de la API de Dataform.

Para usar una función de consulta integrada en un método de JavaScript, sigue estos pasos:

  1. En el panel Files de tu lugar de trabajo de desarrollo, expande definitions/.

  2. Selecciona un archivo JavaScript.

  3. En el archivo, ingresa un método global de JavaScript de Dataform.

  4. En el método, ingresa un argumento ctx contextualizable.

  5. Opcional: Si usas cadenas de plantillas de JavaScript, une el argumento contextual en acentos graves ``.

  6. En el argumento contextualizable, ingresa la función de consulta con su parámetro como un objeto de contexto.

  7. Opcional: Haz clic en Formato.

En la siguiente muestra de código, se muestra la función de consulta ref unida dentro de un argumento contextual del método de publicación:

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

Declara una fuente de datos de flujo de trabajo con JavaScript

Puedes declarar varias fuentes de datos en un archivo de declaración de JavaScript con el método de declaración de JavaScript de Dataform. Para obtener más información sobre el método de declaración, consulta la referencia principal de Dataform. Para obtener más información sobre las fuentes de datos en Dataform, consulta Cómo declarar una fuente de datos.

Para declarar una fuente de datos en un archivo JavaScript, sigue estos pasos:

  1. En el panel Files de tu lugar de trabajo de desarrollo, expande definitions/.

  2. Selecciona un archivo JavaScript.

  3. En el archivo, ingresa el siguiente fragmento de código:

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

    Reemplaza lo siguiente:

    • DATABASE_PROJECT_ID: El ID del proyecto que contiene la fuente de datos
    • BIGQUERY_SCHEMA: Es el conjunto de datos de BigQuery en el que existe la relación externa.
    • RELATION_NAME: Es el nombre de la relación que puedes usar más adelante para hacer referencia a la fuente de datos en Dataform.
  4. Para declarar otra fuente de datos en el mismo archivo, agrega un bloque declare adicional al archivo.

  5. Opcional: Haz clic en Formato.

Define una tabla con JavaScript

Puedes crear una tabla con el método publish de JavaScript de Dataform. Para obtener más información sobre el método de publicación, consulta la referencia principal de Dataform.

Puedes definir los siguientes tipos de tablas:

  • Tabla
  • Tabla incremental
  • Ver

Para obtener más información sobre cómo definir tablas en Dataform, consulta Crea una tabla.

Para definir una tabla en un archivo JavaScript, sigue estos pasos:

  1. En el panel Files de tu lugar de trabajo de desarrollo, expande definitions/.

  2. Selecciona un archivo JavaScript.

  3. En el archivo, ingresa el siguiente fragmento de código:

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

    Reemplaza lo siguiente:

    • TABLE_NAME: El nombre de la tabla.
    • SELECT_QUERY: Es una sentencia SELECT de SQL que define la tabla.
  4. Para establecer el tipo de tabla, agregar dependencias y agregar una descripción, establece las propiedades del objeto del método publish.

  5. Para definir otra tabla en el mismo archivo, repite los pasos 3 y 4.

  6. Opcional: Haz clic en Formato.

Define aserciones manuales con JavaScript

Puedes crear aserciones de SQL manuales en un archivo JavaScript con el método de aserción de JavaScript de Dataform. Para obtener más información sobre el método de afirmación, consulta la referencia principal de Dataform.

Una consulta de SQL de aserción manual debe mostrar cero filas. Si la consulta muestra filas cuando se ejecuta, la aserción falla. Puedes crear varias aserciones en un archivo JavaScript.

Para obtener más información sobre las aserciones en Dataform, consulta Cómo probar tablas con aserciones.

Para crear una aserción manual en un archivo JavaScript, sigue estos pasos:

  1. En el panel Files de tu lugar de trabajo de desarrollo, expande definitions/.

  2. Selecciona un archivo JavaScript.

  3. En el archivo, ingresa el siguiente fragmento de código:

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

    Reemplaza lo siguiente:

    • ASSERTION_NAME: Es el nombre de tu aserción personalizada.
    • CUSTOM_ASSERTION_QUERY: Tu consulta de aserción de SQL
  4. Para crear otra aserción en el mismo archivo, repite el paso 3.

  5. Opcional: Haz clic en Formato.

En la siguiente muestra de código, se muestra una aserción de JavaScript que afirma que ningún valor en source_table es NULL:

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

Define operaciones de SQL personalizadas con JavaScript

Puedes definir operaciones de SQL personalizadas en un archivo JavaScript con el método de JavaScript de operación de Dataform. Para obtener más información sobre las operaciones de SQL personalizadas en Dataform, consulta Cómo agregar operaciones de SQL personalizadas.

Para definir una operación SQL personalizada con JavaScript, sigue estos pasos:

  1. En el panel Files de tu lugar de trabajo de desarrollo, expande definitions/.

  2. Selecciona un archivo JavaScript.

  3. En el archivo, ingresa el siguiente fragmento de código:

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

    Reemplaza lo siguiente:

    • OPERATION_NAME: Es el nombre de la operación personalizada.
    • CUSTOM_SQL_QUERY: Tu consulta de SQL personalizada
  4. Para definir otra operación SQL personalizada en el mismo archivo, repite el paso 3.

  5. Opcional: Haz clic en Formato.

En la siguiente muestra de código, se muestra una operación SQL personalizada en un archivo JavaScript que inserta una sola fila nueva en some_table y establece test_column de la fila nueva en 2:

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

¿Qué sigue?