spark-data-quality
What Is This For?
Imagine your pipeline loads 100,000 rows of sales data into a table every day. Before you use that data to make business decisions, you'd want to check:
- Does the
customer_idcolumn have any blank or missing values? - Did the table receive all 100,000 rows, or did some get lost and only 50,000 arrived?
- Is every value in the
amountcolumn between 1 and 500,000 (no negatives, no unrealistic numbers)? - Does the
regioncolumn only contain expected values like "North", "South", "East", "West" — or did something like "XYZ123" sneak in? - Are there exactly 4 unique regions, not 3 or 50?
Doing these checks manually is impossible at scale. This package automates that process. You define your rules once (in the DQ Engine dashboard), and every time new data arrives, the package checks it against all those rules and tells you what passed and what failed.
If something fails, you know immediately — before bad data reaches your reports, dashboards, or downstream systems.
How It Works
Your Data (DataFrame)
│
▼
┌──────────────────┐ ┌──────────────┐
│ SparkDQAgent │──GET──>│ DQ Engine │ "What rules should I check?"
│ │<───────│ │ (returns assertions)
│ Runs checks │ │ │
│ using Great │ │ │
│ Expectations │──POST─>│ │ "Here are the results"
│ │ │ Stores & │
│ Returns summary │ │ displays │
└──────────────────┘ └──────────────┘
- You create a
SparkDQAgentand point it to your table using catalog, schema, and table name - The agent fetches rules from the DQ Engine (e.g., "column X must not be null")
- You load your data into a Spark DataFrame
- The agent runs every rule against your data
- Results are saved to the DQ Engine and returned to you
Installation
pip install spark-data-quality
Quick Start
from pyspark.sql import SparkSession
from spark_dq.quality import SparkDQAgent
spark = SparkSession.builder.master("local[*]").getOrCreate()
# 1. Create the agent — just pass your table's catalog, schema, and name
agent = SparkDQAgent(
catalog="mycatalog",
schema="myschema",
table="sales_data",
data_quality_url="https://your-dq-engine.example.com/api/v1/spark",
catalog_type="unmanaged",
trino_host="trino.example.com:443",
trino_user="service_account",
trino_pwd="your_password",
)
# 2. Load your data
df = spark.read.format("jdbc") \
.option("url", "jdbc:trino://trino.example.com:443?SSL=true") \
.option("driver", "io.trino.jdbc.TrinoDriver") \
.option("user", "service_account") \
.option("password", "your_password") \
.option("query", "SELECT * FROM mycatalog.myschema.sales_data") \
.load()
# 3. Run checks and review results
results = agent.execute_data_quality(df)
for suite_name, stats in results.items():
passed = stats["successful_expectations"]
total = stats["evaluated_expectations"]
print(f"{suite_name}: {passed}/{total} passed")
spark.stop()
Key Methods
execute_data_quality(df)
The only method you need to call. You pass it your data (a Spark DataFrame) and it does everything else automatically.
What happens when you call it:
results = agent.execute_data_quality(df)
│
│ Step 1 — Fetch rules from DQ Engine
│ ├── Calls the DQ Engine API: "What checks exist for this table?"
│ └── DQ Engine responds with all assertions
│ (e.g., "customer_id not null", "amount between 1-500000")
│
│ Step 2 — Run every check against your data
│ ├── Each assertion is evaluated against every row in your DataFrame
│ ├── Checks run in parallel for speed (multiple checks at the same time)
│ └── Uses Great Expectations under the hood to validate
│
│ Step 3 — Save results to DQ Engine
│ ├── Each check's result (pass/fail/skipped) is sent to the DQ Engine
│ └── Results become visible in the DQ Engine web dashboard
│
│ Step 4 — Return summary to you
│ └── You get back a dictionary showing how many checks passed and failed
What you get back:
{
"sales_data_93": {
"evaluated_expectations": 5,
"successful_expectations": 4,
"unsuccessful_expectations": 1,
"success_percent": 80.0
}
}
This tells you: 5 checks ran, 4 passed, 1 failed — 80% pass rate.
| Field | What It Means |
|---|---|
evaluated_expectations |
Total number of checks that ran |
successful_expectations |
How many passed |
unsuccessful_expectations |
How many failed |
success_percent |
Pass rate (100.0 = all passed) |
If all checks pass → success_percent is 100.0 — your data is clean.
If any check fails → unsuccessful_expectations tells you how many failed. You can review the details in the DQ Engine dashboard to see exactly which column and which rule failed.
Common Assertion Types
| Check | Assertion Type |
|---|---|
| No null values | expect_column_values_to_not_be_null |
| All values unique | expect_column_values_to_be_unique |
| Values in a range | expect_column_values_to_be_between |
| Row count in a range | expect_table_row_count_to_be_between |
| Distinct value count | expect_column_unique_value_count_to_be_between |
| Median in a range | expect_column_median_to_be_between |
| Text matches pattern | expect_column_values_to_match_regex |
| Text length in range | expect_column_value_lengths_to_be_between |
Requirements
- Python 3.8+
- PySpark 3.1.1+
- Great Expectations 0.18.12
- A running DQ Engine instance with assertions configured
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file spark_data_quality-1.1.0.tar.gz.
File metadata
- Download URL: spark_data_quality-1.1.0.tar.gz
- Upload date:
- Size: 14.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a32d48a30dcf0af2fbadb2ad85e79ed5d8fe392b18fceb4264bd0e3750918c37
|
|
| MD5 |
91a2d81b05f40a6e9a25943a8a598125
|
|
| BLAKE2b-256 |
2bdf5e0d2fea4d85e71a362b47535aed1dc3e383a4754c3df051bda189b471aa
|
Provenance
The following attestation bundles were made for spark_data_quality-1.1.0.tar.gz:
Publisher:
ci.yml on saal-core/digixt-quality-package
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
spark_data_quality-1.1.0.tar.gz -
Subject digest:
a32d48a30dcf0af2fbadb2ad85e79ed5d8fe392b18fceb4264bd0e3750918c37 - Sigstore transparency entry: 2343929396
- Sigstore integration time:
-
Permalink:
saal-core/digixt-quality-package@69db27fe9061fa94b4a74b2901ce7b1d91fe74df -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/saal-core
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@69db27fe9061fa94b4a74b2901ce7b1d91fe74df -
Trigger Event:
push
-
Statement type:
File details
Details for the file spark_data_quality-1.1.0-py3-none-any.whl.
File metadata
- Download URL: spark_data_quality-1.1.0-py3-none-any.whl
- Upload date:
- Size: 18.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e224b1d96b7912213fefd513fa256ce0acd4b5c32681a76b8452db08771e88ad
|
|
| MD5 |
f04bdb4c75c48a518026b425c4c4bcc7
|
|
| BLAKE2b-256 |
f42f79027fb184072338e83853ad7b66a4354496af17e056c4a6fecb4889f7f5
|
Provenance
The following attestation bundles were made for spark_data_quality-1.1.0-py3-none-any.whl:
Publisher:
ci.yml on saal-core/digixt-quality-package
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
spark_data_quality-1.1.0-py3-none-any.whl -
Subject digest:
e224b1d96b7912213fefd513fa256ce0acd4b5c32681a76b8452db08771e88ad - Sigstore transparency entry: 2343929412
- Sigstore integration time:
-
Permalink:
saal-core/digixt-quality-package@69db27fe9061fa94b4a74b2901ce7b1d91fe74df -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/saal-core
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@69db27fe9061fa94b4a74b2901ce7b1d91fe74df -
Trigger Event:
push
-
Statement type: