Schema compatibility and transfer safety utility for data pipelines
Project description
Schema Shield
Schema Shield classifies schema changes as SAFE, WARNING, or BREAKING — so you know immediately whether a schema evolution is safe to deploy.
What changed between two schemas — and will it break my pipeline?
Why Schema Shield?
Schema diff tools tell you what changed. Schema Shield tells you what it means.
| Classification | When it applies |
|---|---|
| ✅ SAFE | Change is backward-compatible; pipelines continue working |
| ⚠️ WARNING | Change is risky; review before deploying |
| 💥 BREAKING | Change will cause pipeline failures |
Installation
# Core
pip install schema-shield
# With PySpark / Delta Lake support
pip install "schema-shield[spark]"
# With Databricks SDK support
pip install "schema-shield[databricks]"
Quick Start
from schema_shield import check_schema_transfer, format_result
result = check_schema_transfer(old_schema, new_schema)
print(format_result(result))
────────────────────────────────────────────────────
Schema Shield — Compatibility Report
────────────────────────────────────────────────────
✅ SAFE (1 change)
• Added nullable field 'country' — defaults to null for existing records
⚠️ WARNINGS (1 change)
• Nullable relaxed 'id': False → True — downstream may receive unexpected nulls
💥 BREAKING (2 changes)
• Removed field 'mode' — downstream consumers reading this field will fail
• Type changed 'amount': double → decimal
────────────────────────────────────────────────────
Usage
With Python dict / JSON schemas
Pass schemas as Python dicts. Each field needs a "type" key; "nullable" defaults to True.
from schema_shield import check_schema_transfer, format_result
result = check_schema_transfer(old_schema, new_schema)
# Human-readable report
print(format_result(result))
# JSON string — useful for logging or CI output
print(format_result(result, output_format="json"))
# Raw dict — useful for programmatic checks
classification = format_result(result, output_format="dict")
if classification["breaking"]:
raise SystemExit("Breaking schema changes detected — deployment blocked.")
With the CLI
Compare two JSON schema files directly from your terminal or CI pipeline:
schema-shield compare old_schema.json new_schema.json
Schema file format:
{
"user_id": { "type": "string", "nullable": false },
"revenue": { "type": "double", "nullable": true },
"created_at": { "type": "timestamp", "nullable": true }
}
With PySpark
Pass a live SparkSession and table names — Schema Shield reads the schemas for you:
from schema_shield import compare_tables, format_result
result = compare_tables(spark, "dev.catalog.sales", "prod.catalog.sales")
print(format_result(result))
You can also pass PySpark StructType objects directly into check_schema_transfer — no conversion needed.
With Databricks Delta Lake
Use the CompareDelta adapter to compare live Delta tables or audit schema drift across Delta versions:
from schema_shield.adapters.delta import CompareDelta
checker = CompareDelta(
source_schema="catalog.schema.events",
target_schema="catalog.schema.events_v2", # omit to compare versions of same table
spark_session=spark,
)
# Compare current schemas of two tables
print(checker.compare_delta_tables())
# Compare the same table at two different Delta versions
print(checker.compare_delta_versions(source_version=5, target_version=12))
Output Formats
format_result supports three output formats:
| Format | Returns | Use case |
|---|---|---|
"text" (default) |
str |
Terminal output, logs |
"json" |
str |
CI pipelines, structured logging |
"dict" |
dict |
Programmatic checks, custom reporting |
# Text (default)
format_result(result)
format_result(result, output_format="text")
# JSON string
format_result(result, output_format="json")
# Raw classification dict
format_result(result, output_format="dict")
# → {"safe": [...], "warnings": [...], "breaking": [...]}
Supported Schema Types
| Source | How to use |
|---|---|
Python dict |
Pass directly to check_schema_transfer |
| JSON file | Load with json.load(), pass as dict |
PySpark StructType |
Pass directly — normalized automatically |
| Delta table (live) | Use CompareDelta.compare_delta_tables() |
| Delta table (versions) | Use CompareDelta.compare_delta_versions() |
| Spark table name | Use compare_tables(spark, src, tgt) |
Classification Rules
| Change | Classification | Reason |
|---|---|---|
| Added nullable field | ✅ SAFE | Existing records unaffected; field defaults to null |
| Added non-nullable field | 💥 BREAKING | Existing records violate the NOT NULL constraint |
| Removed field | 💥 BREAKING | Downstream readers of this field will fail |
| Type changed | 💥 BREAKING | Data cannot be implicitly cast |
Nullable True → False |
💥 BREAKING | Existing nulls violate the new constraint |
Nullable False → True |
⚠️ WARNING | Constraint relaxed; downstream may receive unexpected nulls |
Contributing
git clone https://github.com/CHOCKA-LINGAM/schema-shield
pip install -e ".[spark]"
pytest
Pull requests are welcome. CI runs automatically on all PRs.
License
MIT © chocka.dev
Project details
Release history Release notifications | RSS feed
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 schema_shield-1.1.1.tar.gz.
File metadata
- Download URL: schema_shield-1.1.1.tar.gz
- Upload date:
- Size: 11.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e64ddbf0cce8abe83e78f56e049a4b705d7cbb4f3e14bf48faaf08d5a7e0588
|
|
| MD5 |
00eb48fcdd6c737b9d3363c4df45b2ac
|
|
| BLAKE2b-256 |
c5203cfa521ae5326c432b9dbfc1565c40c0c7a99424cad5ab41841bb845a513
|
File details
Details for the file schema_shield-1.1.1-py3-none-any.whl.
File metadata
- Download URL: schema_shield-1.1.1-py3-none-any.whl
- Upload date:
- Size: 11.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b3fcb4a19c7ad88e39f40ac902a5e35ce7c679e9e90ed7572b2ad8e1bfb6c09
|
|
| MD5 |
d2c67bdcd52b86128e685cd47d12642c
|
|
| BLAKE2b-256 |
3a228e0146d2b029d701bfab5a75a52937426edeca44dc4b9b8fb2ff8ed5d11d
|