Defining Checks¶
A check is defined through a typed config class. SparkDQ supports two kinds: row-level checks that validate each record individually, and aggregate checks that evaluate the dataset as a whole. Both can be written directly in Python or loaded declaratively from YAML or JSON.
Every check accepts an optional severity: Severity.CRITICAL (default) marks
failing rows invalid, while Severity.WARNING records the violation but keeps
the rows in pass_df().
We will define the three rules from the introduction scenario:
customer_email must not be null, amount must be positive, and the batch must
contain at least 100 rows.
Python-native¶
For code-driven use (notebooks, CI pipelines), define checks with type-safe
config classes. CheckSet supports both a fluent and a classic style.
from sparkdq.checks import NullCheckConfig, NumericMinCheckConfig, RowCountMinCheckConfig
from sparkdq.core import Severity
from sparkdq.management import CheckSet
check_set = (
CheckSet()
.add_check(
NullCheckConfig(
check_id="email-required",
columns=["customer_email"],
)
)
.add_check(
NumericMinCheckConfig(
check_id="amount-positive",
columns=["amount"],
min_value=0,
)
)
.add_check(
RowCountMinCheckConfig(
check_id="min-volume",
min_count=100,
severity=Severity.WARNING,
)
)
)
from sparkdq.checks import NullCheckConfig, NumericMinCheckConfig, RowCountMinCheckConfig
from sparkdq.core import Severity
from sparkdq.management import CheckSet
check_set = CheckSet()
check_set.add_check(
NullCheckConfig(
check_id="email-required",
columns=["customer_email"],
)
)
check_set.add_check(
NumericMinCheckConfig(
check_id="amount-positive",
columns=["amount"],
min_value=0,
)
)
check_set.add_check(
RowCountMinCheckConfig(
check_id="min-volume",
min_count=100,
severity=Severity.WARNING,
)
)
Choosing severity and check IDs
Use CRITICAL for rules that must hold for a record to be usable, and
WARNING for signals you want to monitor without failing the batch. Give
each check a stable, descriptive check_id — it appears verbatim in
_dq_errors, so email-required reads better in a report than check_1.
Declarative (YAML / JSON)¶
For a metadata-driven or config-as-code approach, the same checks can be defined as dictionaries — for example loaded from a YAML file:
# checks.yml
- check: null-check
check-id: email-required
columns:
- customer_email
- check: numeric-min-check
check-id: amount-positive
columns:
- amount
min-value: 0
- check: row-count-min-check
check-id: min-volume
min-count: 100
severity: warning
Note
SparkDQ does not bundle pyyaml or any config parser. You load the config
into a Python list of dicts; SparkDQ takes it from there.
import yaml
from sparkdq.management import CheckSet
with open("checks.yml") as f:
config = yaml.safe_load(f)
check_set = CheckSet()
check_set.add_checks_from_dicts(config)
Next: validate a DataFrame with this CheckSet.