Ce document présente des exemples de scripts Dataform Core et JavaScript qui que vous pouvez utiliser pour créer un workflow SQL dans Dataform.
Créer des tables
Créer une vue avec Dataform Core
L'exemple de code suivant montre la définition d'une vue appelée new_view
.
dans le fichier definitions/new_view.sqlx
:
config { type: "view" }
SELECT * FROM source_data
Créer une vue matérialisée avec Dataform Core
L'exemple de code suivant montre la définition d'une vue matérialisée appelée
new_materialized_view
dans le fichier definitions/new_materialized_view.sqlx
:
config {
type: "view",
materialized: true
}
SELECT * FROM source_data
Créer une table avec Dataform Core
L'exemple de code suivant montre la définition d'une table appelée new_table
.
dans le fichier definitions/new_table.sqlx
:
config { type: "table" }
SELECT * FROM source_data
Créer une table incrémentielle avec Dataform Core
L'exemple de code suivant montre une table incrémentielle qui
traite de manière incrémentielle les lignes de la table productiondb.logs
:
config { type: "incremental" }
SELECT timestamp, message FROM ${ref("productiondb", "logs")}
${when(incremental(), `WHERE timestamp > (SELECT MAX(timestamp) FROM ${self()})`) }
Utiliser la fonction ref
pour référencer des tables avec Dataform Core
L'exemple de code suivant montre la fonction ref
utilisée pour référencer le
Table source_data
dans le definitions/new_table_with_ref.sqlx
fichier de définition de table:
config { type: "table" }
SELECT * FROM ${ref("source_data")}
Ajouter de la documentation à une table, une vue ou une déclaration avec Dataform Core
L'exemple de code suivant montre les descriptions de tables et de colonnes
dans le fichier de définition de table definitions/documented_table.sqlx
:
config { type: "table",
description: "This table is an example",
columns:{
user_name: "Name of the user",
user_id: "ID of the user"
}
}
SELECT user_name, user_id FROM ${ref("source_data")}
Configurer des tables incrémentielles
Ajouter des lignes de tableau pour les nouvelles dates dans les données sources avec Dataform Core
L'exemple de code suivant montre la configuration d'une table incrémentielle
dans le fichier definitions/incremental_table.sqlx
. Dans cette configuration,
Dataform ajoute une ligne au incremental_table
pour chaque nouvelle date:
config { type: "incremental" }
SELECT date(timestamp) AS date, action
FROM weblogs.user_actions
${ when(incremental(), `WHERE timestamp > (select max(date) FROM ${self()})`)
Prendre régulièrement un instantané d'une table avec Dataform Core
L'exemple de code suivant montre la configuration d'une table incrémentielle dans le
definitions/snapshots_table.sqlx
. Dans cette configuration,
Dataform crée snapshots_table
avec un instantané de
productiondb.customers
à la date spécifiée:
config { type: "incremental" }
SELECT current_date() AS snapshot_date, customer_id, name, account_settings FROM productiondb.customers
${ when(incremental(), `WHERE snapshot_date > (SELECT max(snapshot_date) FROM ${self()})`) }
Créer une table glissante sur 30 jours qui se met à jour de manière incrémentielle avec Dataform Core
L'exemple de code suivant montre la configuration d'une table incrémentielle dans le
definitions/incremental_example.sqlx
. Dans cette configuration,
Dataform crée un incremental_example
temporaire qui se met à jour
de manière incrémentielle et supprime la table 30 jours après sa création:
config {type: "incremental"}
post_operations {
delete FROM ${self()} WHERE date < (date_add(Day, -30, CURRENT_DATE))
}
SELECT
date(timestamp) AS date,
order_id,
FROM source_table
${ when(incremental(), `WHERE timestamp > (SELECT max(date) FROM ${self()})`) }
Créer des opérations SQL personnalisées
Exécuter plusieurs opérations SQL dans un fichier SQLX avec Dataform Core
L'exemple de code suivant montre ;
utilisé pour séparer plusieurs opérations SQL
défini dans definitions/operations.sqlx
:
config { type: "operations" }
DELETE FROM datatable where country = 'GB';
DELETE FROM datatable where country = 'FR';
Exécuter un code SQL personnalisé avant de créer une table avec Dataform Core
L'exemple de code suivant montre une opération SQL personnalisée définie dans le
Bloc pre_operations
du definitions/table_with_preops.sqlx
fichier de définition de table:
config {type: "table"}
SELECT * FROM ...
pre_operations {
INSERT INTO table ...
}
Exécuter un code SQL personnalisé après avoir créé une table avec Dataform Core
L'exemple de code suivant montre une opération SQL personnalisée définie dans le
Bloc post_operations
du definitions/table_with_postops.sqlx
fichier de définition de table:
config {type: "table"}
SELECT * FROM ...
post_operations {
GRANT `roles/bigquery.dataViewer`
ON
TABLE ${self()}
TO "group:allusers@example.com", "user:otheruser@example.com"
}
Valider des tables
Ajouter des assertions à une table, une vue ou une déclaration avec Dataform Core
L'exemple de code suivant montre uniqueKey
, nonNull
,
et rowConditions
ont été ajoutées à definitions/tested_table.sqlx
fichier de définition de table:
config {
type: "table",
assertions: {
uniqueKey: ["user_id"],
nonNull: ["user_id", "customer_id"],
rowConditions: [
'signup_date is null or signup_date > "2022-01-01"',
'email like "%@%.%"'
]
}
}
SELECT ...
Ajouter une assertion personnalisée avec Dataform Core
L'exemple de code suivant montre une assertion personnalisée dans un fichier de définition de table
qui vérifie si les colonnes a
, b
ou c
de source_data
sont null
:
config { type: "assertion" }
SELECT
*
FROM
${ref("source_data")}
WHERE
a is null
or b is null
or c is null
Développer avec JavaScript
Utiliser des variables et des fonctions intégrées avec JavaScript
L'exemple de code suivant montre la variable foo
définie dans un bloc js
.
puis utilisé de manière intégrée dans un fichier SQLX:
js {
const foo = 1;
function bar(number){
return number+1;
}
}
SELECT
${foo} AS one,
${bar(foo)} AS two
Générer une table par pays avec JavaScript
L'exemple de code suivant montre comment utiliser la fonction forEach
pour générer
une table pour chaque pays défini dans countries
dans le
Fichier definitions/one_table_per_country.js
:
const countries = ["GB", "US", "FR", "TH", "NG"];
countries.forEach(country => {
publish("reporting_" + country)
.dependencies(["source_table"])
.query(
ctx => `
SELECT '${country}' AS country
`
);
});
Déclarer plusieurs sources dans un même fichier avec JavaScript
L'exemple de code suivant montre comment déclarer plusieurs sources de données dans le
Fichier definitions/external_dependencies.js
:
declare({
schema: "stripe",
name: "charges"
});
declare({
schema: "shopify",
name: "orders"
});
declare({
schema: "salesforce",
name: "accounts"
});
Déclarer plusieurs sources dans un même fichier avec forEach
L'exemple de code suivant montre comment déclarer plusieurs sources de données avec le
forEach
dans le fichier definitions/external_dependencies.js
:
["charges", "subscriptions", "line_items", "invoices"]
.forEach(source => declare({
schema: "stripe",
name: source
})
);
Supprimer les informations sensibles de toutes les tables contenant des informations permettant d'identifier personnellement l'utilisateur à l'aide de JavaScript
L'exemple de code suivant montre une fonction dans definitions/delete_pii.js
fichier qui supprime les informations sélectionnées dans toutes les tables contenant
Informations permettant d'identifier personnellement l'utilisateur :
const pii_tables = ["users", "customers", "leads"];
pii_tables.forEach(table =>
operate(`gdpr_cleanup: ${table}`,
ctx => `
DELETE FROM raw_data.${table}
WHERE user_id in (SELECT * FROM users_who_requested_deletion)`)
.tags(["gdpr_deletion"]))
);
Ajouter preOps
et postOps
avec JavaScript
L'exemple de code suivant montre la fonction publish
utilisée pour créer une requête
avec preOps
et postOps
dans le
definitions/pre_and_post_ops_example.js
:
publish("example")
.preOps(ctx => `GRANT \`roles/bigquery.dataViewer\` ON TABLE ${ctx.ref("other_table")} TO "group:automation@example.com"`)
.query(ctx => `SELECT * FROM ${ctx.ref("other_table")}`)
.postOps(ctx => `REVOKE \`roles/bigquery.dataViewer\` ON TABLE ${ctx.ref("other_table")} TO "group:automation@example.com"`)
Créer des tables incrémentielles avec JavaScript
L'exemple de code suivant montre la fonction publish
utilisée pour créer une
table incrémentielle dans le fichier definitions/incremental_example.js
:
publish("incremental_example", {
type: "incremental"
}).query(ctx => `
SELECT * FROM ${ctx.ref("other_table")}
${ctx.when(ctx.incremental(),`WHERE timestamp > (SELECT MAX(date) FROM ${ctx.self()}`)}
`)
Remplir une table quotidienne avec JavaScript
L'exemple de code suivant montre comment remplir une table mise à jour quotidiennement dans le
Fichier definitions/backfill_daily_data.js
:
var getDateArray = function(start, end) {
var startDate = new Date(start); //YYYY-MM-DD
var endDate = new Date(end); //YYYY-MM-DD
var arr = new Array();
var dt = new Date(startDate);
while (dt <= endDate) {
arr.push(new Date(dt).toISOString().split("T")[0]);
dt.setDate(dt.getDate() + 1);
}
return arr;
};
var dateArr = getDateArray("2020-03-01", "2020-04-01");
// step 1: create table
operate(`create table`, 'create table if not exists backfill_table (`fields`) `);
// step 2: insert into the table
dateArr.forEach((day, i) =>
operate(`backfill ${day}`
`insert into backfill_table select fields where day = '${day}'`)
);
Réutiliser le code avec des inclusions
Utiliser des variables globales avec JavaScript
L'exemple de code suivant montre la définition de project_id
et first_date
constantes dans includes/constants.js
:
const project_id = "project_id";
const first_date = "'1970-01-01'";
module.exports = {
project_id,
first_date
};
L'exemple de code suivant montre la constante first_date
référencée dans le
Fichier definitions/new_table.sqlx
:
config {type: "table"}
SELECT * FROM source_table WHERE date > ${constants.first_date}
Créer un mappage de pays avec JavaScript
L'exemple de code suivant montre la fonction personnalisée country_group
définie dans
le fichier includes/mapping.js
:
function country_group(country){
return `
case
when ${country} in ('US', 'CA') then 'NA'
when ${country} in ('GB', 'FR', 'DE', 'IT', 'PL', 'SE') then 'EU'
when ${country} in ('AU') then ${country}
else 'Other'
end`;
}
module.exports = {
country_group
};
L'exemple de code suivant montre une définition de table qui utilise le
Fonction country_group
dans definitions/new_table.sqlx
fichier de définition de table:
config { type: "table"}
SELECT
country AS country,
${mapping.country_group("country")} AS country_group,
device_type AS device_type,
sum(revenue) AS revenue,
sum(pageviews) AS pageviews,
sum(sessions) AS sessions
FROM ${ref("source_table")}
GROUP BY 1, 2, 3
L'exemple de code suivant montre la requête définie dans
definitions/new_table.sqlx
compilé en SQL:
SELECT
country AS country,
case
when country in ('US', 'CA') then 'NA'
when country in ('GB', 'FR', 'DE', 'IT', 'PL', 'SE') then 'EU'
when country in ('AU') then country
else 'Other'
end AS country_group,
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, 3
Générer un script SQL avec une fonction JavaScript personnalisée
L'exemple de code suivant montre la fonction personnalisée render_script
défini dans includes/script_builder.js
:
function render_script(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 = { render_script };
L'exemple de code suivant montre une définition de table qui utilise le
Fonction render_script
dans definitions/new_table.sqlx
fichier de définition de table:
config {
type: "table",
tags: ["advanced", "hourly"],
disabled: true
}
${script_builder.render_script(ref("source_table"),
["country", "device_type"],
["revenue", "pageviews", "sessions"]
)}
L'exemple de code suivant montre la requête définie dans
definitions/new_table.sqlx
compilé 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
Configurations d'actions
Charger des fichiers SQL avec des configurations d'action
Les configurations d'action facilitent le chargement de fichiers SQL pur. Vous pouvez définir des configurations d'action
dans actions.yaml
fichiers du dossier definitions
.
Pour en savoir plus sur les types d'actions disponibles et les configurations d'action valides consultez la documentation Configurations Dataform Référence.
L'exemple de code suivant montre la définition d'une vue appelée new_view
dans
Fichier definitions/actions.yaml
:
actions:
- view:
filename: new_view.sql
Le fichier SQL definitions/new_view.sql
, référencé par le code précédent
contient du SQL pur:
SELECT * FROM source_data