Skip to main content

Lightweight data quality validation framework for big data pipelines

Project description

DataGuard

Lightweight data quality validation for big data pipelines

PyPI Python CI License: MIT PRs Welcome


DataGuard is a lightweight data quality validation framework that works with Pandas, PySpark, and SQL databases (MySQL, Hive, Flink, Doris, SelectDB). Define rules declaratively, set pass-rate thresholds, and get rich reports — without the boilerplate.

Install

pip install dqguard            # Pandas engine
pip install dqguard[spark]     # With PySpark support
pip install dqguard[sql]       # With SQL database support
pip install dqguard[mysql]     # MySQL (SQLAlchemy + PyMySQL)
pip install dqguard[hive]      # Hive (SQLAlchemy + PyHive)
pip install dqguard[all]       # Everything

Quick Start

import pandas as pd
from dataguard import DataGuard, RuleSet, not_null, in_range, in_set, regex_match

df = pd.DataFrame({
    "name": ["Alice", "Bob", "Charlie", None, "Eve"],
    "age": [25, 30, -1, 40, 150],
    "email": ["alice@example.com", "invalid", "charlie@example.com", "dana@example.com", "eve@example.com"],
    "status": ["active", "active", "inactive", "active", "unknown"],
})

rules = RuleSet()
rules.add("name", not_null())
rules.add("age", in_range(0, 120))
rules.add("email", regex_match(r"^[\w.-]+@[\w.-]+\.\w+$"))
rules.add("status", in_set(["active", "inactive"]))

report = DataGuard(df).validate(rules)
print(report.summary())
DataGuard Validation Report
Engine: pandas
Total Rules: 4 | Passed: 0 | Failed: 4
Overall Status: INVALID
------------------------------------------------------------
[FAIL] name.not_null | pass_rate=80.00% (threshold=100%) | 4/5 rows passed
[FAIL] age.in_range(0, 120) | pass_rate=80.00% (threshold=100%) | 4/5 rows passed
[FAIL] email.regex_match(...) | pass_rate=80.00% (threshold=100%) | 4/5 rows passed
[FAIL] status.in_set(...) | pass_rate=80.00% (threshold=100%) | 4/5 rows passed

Features

Threshold-based validation

Not every column needs 100% compliance. Set thresholds per rule:

rules.add("middle_name", not_null(), threshold=0.95)    # allow 5% nulls
rules.add("transaction_id", unique(), threshold=0.999)   # 99.9% unique

SQL Database Validation

Validate data directly in your database — no need to load into memory:

from dataguard import DataGuard, RuleSet, not_null, in_range, in_set

rules = RuleSet()
rules.add("user_id", not_null())
rules.add("age", in_range(0, 120))
rules.add("status", in_set(["active", "inactive"]))

# MySQL
guardian = DataGuard.from_sql(
    "mysql://user:pass@localhost/mydb",
    table="users",
    dialect="mysql",
)

# Hive
guardian = DataGuard.from_sql(
    "hive://cluster/default",
    table="events",
    dialect="hive",
)

report = guardian.validate(rules)

Supported dialects: mysql, hive, flink, doris, selectdb

Data profiling

profile = DataGuard(df).profile()
for col, stats in profile.items():
    print(f"{col}: {stats['distinct_count']} distinct, {stats['null_rate']:.2%} nulls")

Works with SQL too:

profile = DataGuard.from_sql(engine, "users", dialect="mysql").profile()

RuleSet from dict

Define rules as data — useful for config-driven pipelines:

from dataguard import RuleSet

config = {
    "name": [{"check": "not_null"}],
    "age": [{"check": "in_range", "params": {"min_val": 0, "max_val": 120}}],
    "email": [{"check": "regex_match", "params": {"pattern": r"^[\w.-]+@[\w.-]+\.\w+$"}}],
}
rules = RuleSet.from_dict(config)

CLI

# Validate a CSV file against a rule config
dqguard validate data.csv --rules rules.json

# Validate a SQL table
dqguard validate --sql "mysql://user:pass@localhost/mydb" --table users --rules rules.json --dialect mysql

# Profile a dataset
dqguard profile data.csv

# Profile a SQL table (JSON output)
dqguard profile --sql "mysql://user:pass@localhost/mydb" --table users --json

JSON export

print(report.to_json())   # for CI/CD integration

HTML visualization

Generate a self-contained, stylish HTML report — no external dependencies:

report = DataGuard(df).validate(rules)

# Save to file
report.to_html("validation_report.html")

# Or get as string
html_string = report.to_html()

Features:

  • Dark Glassmorphism theme with animated SVG icons
  • Circular progress ring for overall pass rate
  • Animated counter cards (total/passed/failed)
  • Expandable failure details with sample data
  • Sensitive column auto-masking
  • Responsive design (desktop, tablet, mobile)
  • XSS-safe with built-in HTML escaping

Raise on failure

# Raise ValidationError if any rule fails — useful in pipelines
report = DataGuard(df).validate(rules, raise_on_error=True)

PySpark

from pyspark.sql import SparkSession
from dataguard import DataGuard, RuleSet, not_null, in_range

spark = SparkSession.builder.appName("dqguard").getOrCreate()
df = spark.read.parquet("s3://my-bucket/data/")

rules = RuleSet()
rules.add("user_id", not_null())
rules.add("age", in_range(0, 120))

report = DataGuard(df).validate(rules)

Built-in Checks

Check Description SQL Support
not_null() Value must not be None/NaN Yes
unique() Column values must be unique Yes
in_range(min, max) Numeric value within range (inclusive) Yes
regex_match(pattern) String matches regex pattern Yes (dialect-dependent)
in_set(values) Value in allowed set Yes
min_length(n) String has at least n characters Yes
max_length(n) String has at most n characters Yes
is_numeric() Value must be numeric Yes
is_email() Value must be a valid email address Yes
is_date(format_str) Value must be a valid date (optional format) Yes
not_empty_string() String must be non-empty (not blank) Yes
max_value(max_val) Column maximum must not exceed max_val Yes
min_value(min_val) Column minimum must not be below min_val Yes
custom(fn, name) Custom validation function No (skipped with warning)

Project Structure

dataguard/
├── __init__.py          # Public API
├── core.py              # DataGuard main class
├── rules.py             # Rule & RuleSet definitions
├── checks.py            # Built-in check functions
├── report.py            # ValidationReport & ValidationResult
├── exceptions.py        # Custom exceptions
├── pandas_engine.py     # Pandas validation backend (vectorized)
├── spark_engine.py      # PySpark validation backend
├── sql_engine.py        # SQL validation backend
├── sql_dialects.py      # SQL dialect definitions
├── cli.py               # CLI entry point
└── py.typed             # PEP 561 type marker

Contributing

Contributions are welcome! See CONTRIBUTING.md for guidelines.

License

MIT License — see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dqguard-0.6.0.tar.gz (47.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dqguard-0.6.0-py3-none-any.whl (40.2 kB view details)

Uploaded Python 3

File details

Details for the file dqguard-0.6.0.tar.gz.

File metadata

  • Download URL: dqguard-0.6.0.tar.gz
  • Upload date:
  • Size: 47.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dqguard-0.6.0.tar.gz
Algorithm Hash digest
SHA256 d6b833c2130f772b83f41f52002975696b60383acc0bbc5733ffd141fdd1826d
MD5 a6f87e8011e466155105a635ee6ed9da
BLAKE2b-256 e60a9f72aea529dfdc732e41e3d40e828a3c616c6700d9e390889a57f9f5c5f4

See more details on using hashes here.

File details

Details for the file dqguard-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: dqguard-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 40.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dqguard-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6731a66dcf17dde14254adb52641fa5198b3e6c05c9c53b4bb975028d8549ea7
MD5 c47036e5cea6fecf787cbeadba36f3f3
BLAKE2b-256 26f01a082fbac0ea1bccddbe7ec4da1d7852e43793be2c945147a53c948d51c9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page