DQX — End-to-end apply + save
One method call: read, check, write valid rows, (optionally) write quarantined rows.
from databricks.labs.dqx import check_funcs
from databricks.labs.dqx.engine import DQEngine
from databricks.labs.dqx.rule import DQRowRule, DQDatasetRule
from databricks.labs.dqx.config import InputConfig, OutputConfig
from databricks.sdk import WorkspaceClient
# `spark` is available in Databricks notebooks / jobs. Locally, create it with
# `from pyspark.sql import SparkSession; spark = SparkSession.builder.getOrCreate()`.
dq = DQEngine(WorkspaceClient())
checks = [
DQRowRule(criticality="warn", check_func=check_funcs.is_not_null, column="col3"),
DQDatasetRule(criticality="error", check_func=check_funcs.is_unique, columns=["col1", "col2"]),
]
# Split into valid + quarantine tables
dq.apply_checks_and_save_in_table(
checks=checks,
input_config=InputConfig(location="catalog.schema.input"),
output_config=OutputConfig(location="catalog.schema.valid"),
quarantine_config=OutputConfig(location="catalog.schema.quarantine"),
)
# Or — keep everything in a single annotated output table
dq.apply_checks_and_save_in_table(
checks=checks,
input_config=InputConfig(location="catalog.schema.input"),
output_config=OutputConfig(location="catalog.schema.annotated"),
)
# Or — quarantine only: write just the invalid rows, skip the valid output table
dq.apply_checks_and_save_in_table(
checks=checks,
input_config=InputConfig(location="catalog.schema.input"),
quarantine_config=OutputConfig(location="catalog.schema.quarantine"),
)
output_config is optional, but at least one of output_config / quarantine_config must be provided — omitting both raises InvalidParameterError. Omit output_config (with quarantine_config set) to write only the invalid rows.
Metadata form (checks loaded from storage)
dq.apply_checks_by_metadata_and_save_in_table(
checks=checks_metadata, # list[dict] — see dqx-define-checks
input_config=InputConfig(location="catalog.schema.input"),
output_config=OutputConfig(location="catalog.schema.valid"),
quarantine_config=OutputConfig(location="catalog.schema.quarantine"),
)
If checks is omitted and checks_location is set on a RunConfig (workspace install flow), checks are loaded automatically from that storage — see dqx-storage.
InputConfig / OutputConfig — common options
location — Unity Catalog table (catalog.schema.table) or Unity Catalog Volume path (/Volumes/catalog/schema/volume/...).
format — default delta; set when writing to a volume as parquet/json/csv.
options — dict passed through to reader/writer (e.g. {"mergeSchema": "true"}).
mode — "append" (default for batch) or "overwrite".
- Streaming — set
input_config.is_streaming=True to opt into incremental reads. Provide options={"checkpointLocation": "/Volumes/.../checkpoints/xxx"} on the output config. DQX's batch-style incremental reader uses an AvailableNow-style trigger by default; set a different trigger via the output config if you need continuous streaming. Full details: Applying Quality Checks.
Multi-table / pattern execution
apply_checks_and_save_in_tables(run_configs) — accept a list of RunConfig and fan out over each (input, output, quarantine) triple.
apply_checks_and_save_in_tables_for_patterns(patterns, checks_location, run_config_template=...) — expand wildcard patterns (Python list[str], e.g. ["main.product001.*", "main.product002"]) against Unity Catalog and reuse one RunConfig template for every matched table. Output / quarantine names are derived from the input name + output_table_suffix / quarantine_table_suffix (defaults _dq_output / _dq_quarantine). A template with only quarantine_config set (no output_config) writes the quarantine table per match and skips the valid output. The semicolon-delimited form is a convention of the databricks labs dqx CLI, not the Python API.
Do / Don't
- Do set a unique
checkpointLocation per output when using streaming — DQX uses it to track watermarks; sharing one across pipelines causes silent data loss.
- Do point
quarantine_config at a separate table. Without it, failed rows get the _errors column but remain in the single output table. To persist only the invalid rows, set quarantine_config and omit output_config.
- Do use the same method signature for batch and streaming — the difference is one
is_streaming flag on InputConfig.
- Don't manually pre-filter
_errors.isNull() before writing — DQX already routes error-criticality rows to quarantine_config when you provide it.
- Don't mix
checks= and checks_location in a RunConfig — pick one source of truth.
Canonical docs:
1---2name: dqx-end-to-end3description: Run DQX validation end-to-end — read an input table or path, apply checks, and write valid and quarantined rows to output locations — in a single call. Use when the user asks for "apply and save", "quality-check a table and split the output", "DQX on a whole table", "save valid and invalid rows", or wants to drop DQX into a Lakeflow / workflow that runs on a table or path. Covers apply_checks_and_save_in_table, the by_metadata variant, InputConfig / OutputConfig, and incremental streaming mode.4---56# DQX — End-to-end apply + save78One method call: read, check, write valid rows, (optionally) write quarantined rows.910```python11from databricks.labs.dqx import check_funcs12from databricks.labs.dqx.engine import DQEngine13from databricks.labs.dqx.rule import DQRowRule, DQDatasetRule14from databricks.labs.dqx.config import InputConfig, OutputConfig15from databricks.sdk import WorkspaceClient16# `spark` is available in Databricks notebooks / jobs. Locally, create it with17# `from pyspark.sql import SparkSession; spark = SparkSession.builder.getOrCreate()`.1819dq = DQEngine(WorkspaceClient())2021checks = [22 DQRowRule(criticality="warn", check_func=check_funcs.is_not_null, column="col3"),23 DQDatasetRule(criticality="error", check_func=check_funcs.is_unique, columns=["col1", "col2"]),24]2526# Split into valid + quarantine tables27dq.apply_checks_and_save_in_table(28 checks=checks,29 input_config=InputConfig(location="catalog.schema.input"),30 output_config=OutputConfig(location="catalog.schema.valid"),31 quarantine_config=OutputConfig(location="catalog.schema.quarantine"),32)3334# Or — keep everything in a single annotated output table35dq.apply_checks_and_save_in_table(36 checks=checks,37 input_config=InputConfig(location="catalog.schema.input"),38 output_config=OutputConfig(location="catalog.schema.annotated"),39)4041# Or — quarantine only: write just the invalid rows, skip the valid output table42dq.apply_checks_and_save_in_table(43 checks=checks,44 input_config=InputConfig(location="catalog.schema.input"),45 quarantine_config=OutputConfig(location="catalog.schema.quarantine"),46)47```4849`output_config` is optional, but **at least one** of `output_config` / `quarantine_config` must be provided — omitting both raises `InvalidParameterError`. Omit `output_config` (with `quarantine_config` set) to write only the invalid rows.5051## Metadata form (checks loaded from storage)5253```python54dq.apply_checks_by_metadata_and_save_in_table(55 checks=checks_metadata, # list[dict] — see dqx-define-checks56 input_config=InputConfig(location="catalog.schema.input"),57 output_config=OutputConfig(location="catalog.schema.valid"),58 quarantine_config=OutputConfig(location="catalog.schema.quarantine"),59)60```6162If `checks` is omitted and `checks_location` is set on a `RunConfig` (workspace install flow), checks are loaded automatically from that storage — see `dqx-storage`.6364## InputConfig / OutputConfig — common options6566- **`location`** — Unity Catalog table (`catalog.schema.table`) or Unity Catalog Volume path (`/Volumes/catalog/schema/volume/...`).67- **`format`** — default `delta`; set when writing to a volume as parquet/json/csv.68- **`options`** — dict passed through to reader/writer (e.g. `{"mergeSchema": "true"}`).69- **`mode`** — `"append"` (default for batch) or `"overwrite"`.70- **Streaming** — set `input_config.is_streaming=True` to opt into incremental reads. Provide `options={"checkpointLocation": "/Volumes/.../checkpoints/xxx"}` on the output config. DQX's batch-style incremental reader uses an `AvailableNow`-style trigger by default; set a different trigger via the output config if you need continuous streaming. Full details: [Applying Quality Checks](https://databrickslabs.github.io/dqx/docs/guide/quality_checks_apply).7172## Multi-table / pattern execution7374- **`apply_checks_and_save_in_tables(run_configs)`** — accept a list of `RunConfig` and fan out over each `(input, output, quarantine)` triple.75- **`apply_checks_and_save_in_tables_for_patterns(patterns, checks_location, run_config_template=...)`** — expand wildcard patterns (Python `list[str]`, e.g. `["main.product001.*", "main.product002"]`) against Unity Catalog and reuse one `RunConfig` template for every matched table. Output / quarantine names are derived from the input name + `output_table_suffix` / `quarantine_table_suffix` (defaults `_dq_output` / `_dq_quarantine`). A template with only `quarantine_config` set (no `output_config`) writes the quarantine table per match and skips the valid output. The semicolon-delimited form is a convention of the `databricks labs dqx` CLI, **not** the Python API.7677## Do / Don't7879- **Do** set a unique `checkpointLocation` per output when using streaming — DQX uses it to track watermarks; sharing one across pipelines causes silent data loss.80- **Do** point `quarantine_config` at a separate table. Without it, failed rows get the `_errors` column but remain in the single output table. To persist only the invalid rows, set `quarantine_config` and omit `output_config`.81- **Do** use the same method signature for batch and streaming — the difference is one `is_streaming` flag on `InputConfig`.82- **Don't** manually pre-filter `_errors.isNull()` before writing — DQX already routes error-criticality rows to `quarantine_config` when you provide it.83- **Don't** mix `checks=` and `checks_location` in a `RunConfig` — pick one source of truth.8485Canonical docs:86- End-to-end apply patterns: <https://databrickslabs.github.io/dqx/docs/guide/quality_checks_apply#applying-checks-defined-with-dqx-classes>87- Config dataclasses: <https://databrickslabs.github.io/dqx/docs/reference/engine>88- Demos: <https://databrickslabs.github.io/dqx/docs/demos>