Skip to main content

Detect breaking schema changes in SQL migrations, data models, and schema files before they reach production

Project description

๐Ÿ›ก๏ธ SchemaGuard

Catch breaking schema changes before they reach production.

CI PyPI version License: MIT GitHub Sponsors

A GitHub Action and CLI that scans SQL migrations, Pydantic models, Avro schemas, Protobuf files, and dbt models for changes that will break your application or data pipeline โ€” and explains exactly what to fix.


Why?

Schema changes are the #1 cause of production data incidents that nobody sees coming. A developer drops a column in a migration, the PR review looks fine, tests pass, and it ships on Friday afternoon. By Saturday morning the app is returning 500s because a critical query references a column that no longer exists. The post-mortem always says the same thing: "We didn't connect the migration to the application code."

The problem compounds in data pipelines. A RENAME TABLE in an Alembic migration breaks three downstream dbt models, two Kafka consumers, and a Spark job โ€” none of which are in the same repository. Existing CI tools catch syntax errors and test failures, but they have no awareness of structural compatibility between your schema and everything that depends on it.

SchemaGuard closes that gap by running in CI as a GitHub Action or local CLI. It diffs your branch against a base ref, classifies every schema change by severity, and fails the build before a breaking change can merge. No config files, no external services, no dependencies beyond the Python standard library โ€” just a fast, transparent analysis of the diff that already exists in your PR.


โœจ What It Catches

๐Ÿ—„๏ธ SQL Migrations (Alembic, Django, Flyway, Liquibase, raw SQL)

Operation Severity
DROP TABLE ๐Ÿ”ด Critical
DROP COLUMN ๐Ÿ”ด Critical
TRUNCATE ๐Ÿ”ด Critical
RENAME COLUMN / RENAME TABLE ๐ŸŸ  High
ALTER COLUMN ... TYPE ๐ŸŸ  High
NOT NULL without DEFAULT ๐ŸŸ  High
DROP CONSTRAINT / DROP PRIMARY KEY ๐ŸŸ  High
DROP INDEX ๐ŸŸก Medium
DROP VIEW ๐ŸŸก Medium

๐Ÿ“ Python Data Models

Change Severity
Pydantic BaseModel field removed ๐Ÿ”ด Critical
SQLAlchemy Column removed ๐Ÿ”ด Critical
TypedDict key removed ๐ŸŸ  High
@dataclass field removed ๐ŸŸก Medium
Pydantic validator removed ๐ŸŸข Low

๐Ÿ“„ Schema Files

Change Severity
Avro field removed (.avsc) ๐Ÿ”ด Critical
Protobuf field removed (.proto) ๐Ÿ”ด Critical
JSON Schema required field removed ๐ŸŸ  High
dbt column removed from schema.yml ๐ŸŸ  High

๐Ÿ”ท GraphQL Schemas (.graphql, .gql)

Change Severity
Type removed ๐Ÿ”ด Critical
Field removed from type ๐Ÿ”ด Critical
Field changed from non-null to nullable ๐ŸŸ  High
Enum value removed ๐ŸŸ  High
Interface removed ๐ŸŸ  High
Input field removed ๐ŸŸ  High
Directive removed ๐ŸŸก Medium

๐Ÿ”บ Prisma Schema (schema.prisma)

Change Severity
Model removed ๐Ÿ”ด Critical
Model field removed ๐Ÿ”ด Critical
Primary key (@id) removed ๐Ÿ”ด Critical
Unique/index constraint removed ๐ŸŸ  High
Relation removed ๐ŸŸ  High
Enum removed ๐ŸŸ  High
Field default removed ๐ŸŸก Medium

๐Ÿ Django Models

Change Severity
Model class removed ๐Ÿ”ด Critical
Field removed ๐Ÿ”ด Critical
ForeignKey removed ๐Ÿ”ด Critical
OneToOneField removed ๐Ÿ”ด Critical
ManyToManyField removed ๐ŸŸ  High
unique=True removed ๐ŸŸ  High
db_table changed ๐ŸŸ  High

๐Ÿš€ Quick Start

GitHub Action

name: Schema Safety Check

on: [pull_request]

jobs:
  schemaguard:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0
      - uses: Tahiram32/schemaguard@v0.2.0
        with:
          base-ref: origin/main
          format: github
          fail-on: high

CLI

# New installation
pip install schema-guardian

# Existing users โ€” upgrade to v0.2.0
pip install --upgrade schema-guardian

# Diff current branch against origin/main
schemaguard --base origin/main

# Output as Markdown
schemaguard --base origin/main --format markdown

# Output as SARIF for GitHub Code Scanning
schemaguard --base origin/main --format sarif > results.sarif

# Generate a status badge
schemaguard --base origin/main --badge

โš™๏ธ Configuration

All options are available as CLI flags and as GitHub Action inputs.

Flag / Input Default Description
--repo / repo $GITHUB_WORKSPACE Path to the repository root to scan
--base / base-ref origin/main Git ref to diff against
--format / format markdown Output format: text, json, markdown, github, sarif
--fail-on / fail-on high Minimum risk level for non-zero exit: none, low, medium, high, critical
--badge / badge false Write schemaguard-badge.svg to the repository root

Output Formats

  • text โ€” plain-text summary for terminals
  • json โ€” machine-readable JSON array of findings
  • markdown โ€” GitHub-flavoured Markdown table (default)
  • github โ€” GitHub Actions workflow commands (::error::, ::warning::)
  • sarif โ€” SARIF 2.1.0 for GitHub Code Scanning upload

๐Ÿšซ Ignore Rules (.schemaguardignore)

Create a .schemaguardignore file in your repo root to suppress known-safe findings:

# Ignore specific files or glob patterns
tests/fixtures/**
migrations/squash_*.sql
seeds/

# Ignore findings whose message contains a substring
[ignore-messages]
NOT NULL constraint added

Pass a custom ignore file path with --ignore-file /path/to/file.


๐Ÿ”ฌ How It Works

SchemaGuard operates in three independent analysis layers, each targeting a different class of schema artifact.

1. migration_analyzer โ€” Runs git diff <base>...HEAD and extracts all changed SQL and migration files (.sql, Alembic versions/, Django migrations/, Flyway V*.sql, Liquibase changelogs). It then applies a set of pattern rules against the added lines to detect dangerous DDL operations ranked by severity.

2. model_analyzer โ€” Parses the diff for changes to Python source files and identifies removed class attributes in BaseModel, DeclarativeBase/Column, TypedDict, and @dataclass definitions. Field removal is detected by comparing the set of defined names in the before/after snapshots of each class.

3. schema_file_analyzer โ€” Handles structured schema formats: Avro (.avsc), Protobuf (.proto), JSON Schema (.json/.yaml with $schema), and dbt schema.yml. For each file type it parses the before/after states of changed files and computes structural diffs to detect removed fields, required properties, and column definitions.

All three analyzers produce a unified list of Finding objects with a file path, line number, description, and severity. The CLI aggregates these into the requested output format and exits with a non-zero code if any finding meets or exceeds the --fail-on threshold.


๐Ÿ—บ๏ธ Roadmap

  • SQL migration danger detection (DROP, RENAME, ALTER TYPE, NOT NULL)
  • Pydantic / SQLAlchemy / dataclass model analysis
  • Avro, Protobuf, JSON Schema file diffing
  • dbt schema.yml column change detection
  • SARIF output for GitHub Code Scanning
  • GitHub Action composite workflow
  • GraphQL schema change detection
  • Prisma schema support
  • Django model field analysis
  • Custom ignore rules via .schemaguardignore

โค๏ธ Sponsor

If SchemaGuard saves you from a production incident, consider sponsoring continued development:

github.com/sponsors/Tahiram32


Contributing

See CONTRIBUTING.md for how to get started. All contributions are welcome โ€” bug reports, feature requests, and pull requests.

License

MIT ยฉ 2026 Tahiram32 โ€” 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

schema_guardian-0.2.0.tar.gz (20.2 kB view details)

Uploaded Source

Built Distribution

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

schema_guardian-0.2.0-py3-none-any.whl (23.6 kB view details)

Uploaded Python 3

File details

Details for the file schema_guardian-0.2.0.tar.gz.

File metadata

  • Download URL: schema_guardian-0.2.0.tar.gz
  • Upload date:
  • Size: 20.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for schema_guardian-0.2.0.tar.gz
Algorithm Hash digest
SHA256 b75ffd9d3d13f3b0c376ff6ec6bb00e86b06857be8b568bafd4289716c78f0a8
MD5 5e677619421f5e91d6f0e5df354ed869
BLAKE2b-256 36aa30ecda21e763969feb08d8a8575a50373a723b98c16da6a0f5403316658e

See more details on using hashes here.

File details

Details for the file schema_guardian-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for schema_guardian-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 242d51d0d89a4dff3f9c6882ba8d2964f44aff29621f0ffbba95b6dd58616464
MD5 151be51712a381581d37c77e6d2d7743
BLAKE2b-256 40e6e7fa305cf3304fc6f19aea8269be0b3071352bd3728250b805d62ee45e17

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