Dataform Core Documentation
repository·main·Indexed 21 days ago
https://github.com/dataform-co/dataformAn open-source meta-language for building scalable SQL transformation pipelines in BigQuery. Dataform Core provides dependency management, automated data quality testing via assertions, and data documentation. It includes a CLI for local development, project initialization, compilation of SQLX projects into execution graphs, and integration options for Google Cloud Platform.
What's inside Dataform Core
- The Stackoverflow Reporter is an example project designed to demonstrate how to retrieve and process analytics for Stack Overflow posts and users using Dataform.
What is Dataform Core
mainDataform Core is an open-source meta-language designed to create SQL tables and workflows in BigQuery. It extends standard SQL by adding:
- Dependency Management: A system to manage relationships between different data assets.
- Automated Data Quality Testing: Built-in mechanisms for assertions and checks.
- Data Documentation: Tools to document your data assets.
It allows data teams to build scalable SQL transformation pipelines using software engineering best practices like version control and testing.
Configure uniqueKey for incremental merges
mainWhile the.uniqueKey()method is deprecated in favor ofIncrementalTableConfig.uniqueKey, setting a unique key allows Dataform to perform aMERGEinstead of anAPPENDduring incremental runs. The unique key is a set of column names used to identify rows for updating.Write unit tests for SQL using the Test class
mainDataform test actions allow you to write unit tests for your generated SQL. You can implement tests using either SQLX files or the Javascript API.
Using SQLX
In a
.sqlxfile, set thetypeto"test"in theconfigblock. You can define inputs using theinputblock to provide mock data for the test.Using the Javascript API
Use the
test("name")function. The methodsinput()andexpect()are available on the object returned bytest().input(refName, contextableQuery): Sets the input query (mock data) to test against.expect(contextableQuery): Sets the expected output of the query being tested.
// Using SQLX -- definitions/name.sqlx config { type: "test" } input "foo" { SELECT 1 AS bar } SELECT 1 AS bar // Using Javascript API // definitions/file.js test("name") .input("sample_data", `SELECT 1 AS bar`) .expect(`SELECT 1 AS bar`); publish("sample_data", { type: "table" }).query("SELECT 1 AS bar")Migrate from the deprecated Dataform VS Code extension
mainThe Dataform VS Code extension is deprecated and will no longer receive updates. To continue working with Dataform in your IDE or cloud environment, migrate to one of the following alternatives:
- Open sourced alternative: dataform-lsp-vscode
- Google Cloud Dataform UI: Google Cloud Dataform
Create tables in Dataform
mainTables are the fundamental building blocks in Dataform. Dataform compiles your code into SQL, executes it, and creates the defined tables in BigQuery. You can define tables using three different methods:
- SQLX files: Use a
.sqlxfile with aconfigblock. - Action config files: Use a
.yamlfile to map actions to existing.sqlfiles. - Javascript API: Use the
table()function within a.jsfile.
Note: When using the Javascript API, configuration methods are accessed via the object returned by the
table()function.-- Using a SQLX file -- definitions/name.sqlx config { type: "table" } SELECT 1# Using action configs files # definitions/actions.yaml actions: - table: filename: name.sql// Using the Javascript API // definitions/file.js table("name", { type: "table" }).query("SELECT 1 AS TEST")- SQLX files: Use a
Create an incremental table using SQLX
mainTo define an incremental table in a
.sqlxfile, set thetypetoincrementalwithin theconfigblock. Use theincremental()function within your SQL to differentiate between the initial full build and subsequent incremental runs (e.g., to filter for only new rows).-- definitions/name.sqlx config { type: "incremental" } -- This inserts `1` the first time running, and `2` on subsequent runs. SELECT ${when(incremental(), 1, 2) }-- definitions/name.sqlx config { type: "incremental" } -- This inserts `1` the first time running, and `2` on subsequent runs. SELECT ${when(incremental(), 1, 2) }Set up the Dataform VS Code extension
mainTo use this extension, you must have the Dataform CLI installed globally on your system. You can install it using npm:
npm i -g @dataform/cliOnce installed, the extension provides:
- Syntax highlighting for
.sqlxfiles. - Realtime compilation of your project.
- Navigation: Use
cmd + click(orctrl + clickon Windows/Linux) on aref()function to jump to the referenced file.
- Syntax highlighting for
Create an assertion in Dataform
mainAn assertion is a data quality test query. If the query returns any rows, the assertion fails. You can create assertions using four different methods:
- SQLX file: Define the assertion type in a
configblock. - Table configuration: Add assertions directly to the
assertionsproperty within a table's config block. - Action config files (YAML): Define the assertion in a
.yamlfile and point to a corresponding.sqlfile. - Javascript API: Use the
assert()function and chain the.query()method.
Note: When using the Javascript API, configuration methods are accessed via the object returned by
assert().-- Using a SQLX file -- definitions/name.sqlx config { type: "assertion" } SELECT * FROM table WHERE a IS NULL# Using action configs files # definitions/actions.yaml actions: - assertion: filename: name.sql// Using the Javascript API // definitions/file.js assert("name").query("SELECT * FROM table WHERE a IS NULL")- SQLX file: Define the assertion type in a
Create a Notebook action
mainNotebooks allow you to run Jupyter Notebook (
.ipynb) files within Dataform. The output is sent to the storage buckets defined in yourworkflow_settings.yamlfile.You can define a notebook action using either YAML configuration files or the JavaScript API.
// Using the Javascript API notebook("name", { filename: "name.ipynb" }) // Using action configs files (YAML) # definitions/actions.yaml actions: - notebook: filename: name.ipynbCreate a custom Dataform package
mainTo create a new Dataform package, follow these steps:
Clone the base package repository: Use the
dataform-package-baserepository as your starting point. This repo provides the necessary structure, includingindex.js,example.js, andREADME.md.- Repository: https://github.com/dataform-co/dataform-package-base
- Ensure the repository is public if you intend to share it.
Implement package functionality: Modify the base files to implement your logic. The base repo contains a simple dependency graph (one declaration and two chained tables). At a minimum, you should update the following files to reflect your package's purpose:
README.mdindex.jsexample.jsincludes/dataset_one.jsincludes/dataset_two.js
Test against a data warehouse: Connect your package to a live data warehouse to verify that the dependency graph and transformations behave as expected.
Release: Once verified, you can share your package with the community. If you want your package listed in the official documentation, submit a pull request to the Dataform repository.
Create an incremental table using the Javascript API
mainYou can create incremental tables using the
publishfunction in a.jsfile. Pass{ type: "incremental" }as the configuration object. Thequerymethod is called on the returned object to define the SQL logic. Usectx.incremental()within the query context to handle incremental logic.// definitions/file.js publish("name", { type: "incremental" }).query( ctx => `SELECT ${ctx.when(ctx.incremental(), 1, 2) }` )