SparkDQ — Data Quality Validation for Apache Spark
SparkDQ is a lightweight data quality framework built natively for PySpark. You describe what valid data looks like — declaratively via YAML/JSON or through a type-safe Python API — and it validates your DataFrame at row and aggregate level in a single pass.
Its defining trait is what it leaves out. SparkDQ is intentionally small in scope and low in complexity — a focused set of checks and a single-pass engine, with no metadata store, orchestration layer, or profiling engine to operate. For most pipelines, that is exactly enough, and the reduced complexity is a feature in itself. That focus is what sets it apart: no JVM bridge like PyDeequ, no complexity overhead like Great Expectations, and no platform lock-in like Databricks dqx.
One dependency. No wrappers. No bloat.
Quickstart
Declarative — checks are passed as dicts, loaded from anywhere: YAML files, JSON, databases, or APIs:
from pyspark.sql import SparkSession
from sparkdq.engine import BatchDQEngine
from sparkdq.management import CheckSet
spark = SparkSession.builder.getOrCreate()
df = spark.createDataFrame(
[
{"id": 1, "name": "Alice"},
{"id": 2, "name": None},
{"id": 3, "name": "Bob"},
]
)
check_set = CheckSet()
check_set.add_checks_from_dicts([
{"check": "null-check", "check-id": "no-null-name", "columns": ["name"]},
])
result = BatchDQEngine(check_set).run_batch(df)
print(result.summary())
# Validation Summary (2024-01-01 00:00:00)
# Total records: 3
# Passed records: 2
# Failed records: 1
# Warnings: 0
# Pass rate: 67.00%
Python-native — full type safety and IDE autocompletion:
from pyspark.sql import SparkSession
from sparkdq.checks import NullCheckConfig
from sparkdq.core import Severity
from sparkdq.engine import BatchDQEngine
from sparkdq.management import CheckSet
spark = SparkSession.builder.getOrCreate()
df = spark.createDataFrame(
[
{"id": 1, "name": "Alice"},
{"id": 2, "name": None},
{"id": 3, "name": "Bob"},
]
)
check_set = (
CheckSet()
.add_check(NullCheckConfig(check_id="no-null-name", columns=["name"], severity=Severity.CRITICAL))
)
result = BatchDQEngine(check_set).run_batch(df)
print(result.summary())
# Validation Summary (2024-01-01 00:00:00)
# Total records: 3
# Passed records: 2
# Failed records: 1
# Warnings: 0
# Pass rate: 67.00%
SparkDQ ships with 30+ built-in checks across null validation, numeric ranges, string patterns, date boundaries, schema enforcement, uniqueness, and referential integrity.
🚀 See the official documentation to learn more.
Installation
For Local Development / Standalone Clusters
Install with PySpark included:
pip install sparkdq[spark]
For Databricks / Managed Platforms
Install without PySpark (runtime provided by platform):
pip install sparkdq
The framework supports Python 3.11+ and is fully tested with PySpark 3.5.x. SparkDQ will automatically check for PySpark availability on import and provide clear error messages if PySpark is missing in your environment.
Why SparkDQ?
-
Small on purpose: A focused scope and low complexity — quick to learn, hard to misconfigure, and enough for most pipelines
-
Extensible by design: Add custom checks via a simple plugin system — no changes to the core required
-
Declarative or Pythonic: YAML/JSON configs or type-safe Python — your choice
-
Severity-aware: Distinguish between hard failures (CRITICAL) and soft constraints (WARNING)
-
Row-level and aggregate: Validate individual records and entire datasets in a single pass
-
Minimal footprint: Only Pydantic required — PySpark is provided by your platform
Let’s Build Better Data Together
⭐️ Found this useful? Give it a star and help spread the word!
📣 Questions, feedback, or ideas? Open an issue or discussion — we’d love to hear from you.
🤝 Want to contribute? Check out CONTRIBUTING.md to get started.
Metadata
Release files for sparkdq 0.12.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sparkdq-0.12.1.tar.gz | 279.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sparkdq-0.12.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 375.0 kB
Release files / sparkdq-0.12.1.tar.gz
| Download URL | sparkdq-0.12.1.tar.gz |
|---|---|
| Size | 279.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cbffbceceadf0690be803b21b789ad3bef4bbee7ea0eaa1af98b14dc8265e9d5
|
|
BLAKE2b-256 checksum How to use checksums |
bef95511607913b9e0419187f58629b57bc7d196cfb37a549a02e27bdd081fa6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / sparkdq-0.12.1-py3-none-any.whl
| Download URL | sparkdq-0.12.1-py3-none-any.whl |
|---|---|
| Size | 95.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bc01e27c8ea3762a0e639d590780f00fff6489c39537f02f0438db94df0b1377
|
|
BLAKE2b-256 checksum How to use checksums |
b812785f27bc35198462127506aad80a85535fde7d7a4792f95437caa60601c5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|