Deterministic SQL Change Impact Analyzer
Project description
Schema Change Impact Analyzer (SCIA)
Predict schema change risks before they break production.
SCIA analyzes SQL schema changes and tells you:
- โ What will break
- โ How risky it is (LOW/MEDIUM/HIGH)
- โ Why it matters
Works with JSON exports, SQL migration files, or live warehouse connections.
๐ Quick Start
1. Install
pip install scia-core
2. Prepare Schema Files
Create two JSON files representing your schema before and after the change:
before_schema.json โ Original schema
[
{
"schema_name": "analytics",
"table_name": "customers",
"columns": [
{
"column_name": "customer_id",
"data_type": "INT",
"is_nullable": false,
"ordinal_position": 1
},
{
"column_name": "email",
"data_type": "VARCHAR",
"is_nullable": true,
"ordinal_position": 2
}
]
}
]
after_schema.json โ Modified schema (e.g., removed email column)
[
{
"schema_name": "analytics",
"table_name": "customers",
"columns": [
{
"column_name": "customer_id",
"data_type": "INT",
"is_nullable": false,
"ordinal_position": 1
}
]
}
]
3. Run Analysis
JSON Mode (Offline):
scia analyze --before before_schema.json --after after_schema.json --format markdown
SQL Mode (Migration Analysis): Analyze risk of applying a SQL migration to an existing schema (JSON or DB).
# Apply migration.sql to schema in base_schema.json
scia analyze --before base_schema.json --after migration.sql --format markdown
# Specify dialect for SQL parsing (currently only snowflake fully supported)
scia analyze --before base_schema.json --after migration.sql --dialect snowflake --format markdown
Supported ALTER operations: ADD COLUMN, DROP COLUMN, RENAME COLUMN, ALTER COLUMN (TYPE/NULLABILITY).
Database Mode (Live):
scia analyze --before PROD.ANALYTICS --after DEV.ANALYTICS --warehouse snowflake --format markdown
4. Get Risk Assessment
Output (Markdown):
RISK: HIGH
Classification: HIGH
Risk Score: 80
Findings:
1. COLUMN_REMOVED (Severity: HIGH)
- Column 'email' removed from table 'customers'
- Evidence: table=customers, column=email
[!NOTE] New to v0.2? Check out the Advanced Usage Guide for SQL migration analysis, live database connections, and dependency analysis features.
๐ Common Use Cases
Use Case 1: Column Removal
Scenario: Remove a column you think is unused
scia analyze \
--before before_schema.json \
--after after_schema.json \
--format markdown
Output:
- โ Detects if downstream views depend on this column
- โ Warns about join key changes
- โ Scores risk (HIGH if widely used)
Use Case 2: Type Change
Scenario: Change INT column to STRING
# before_schema.json: "data_type": "INT"
# after_schema.json: "data_type": "VARCHAR"
scia analyze \
--before before_schema.json \
--after after_schema.json \
--format json
Output:
- โ Identifies type incompatibility
- โ Warns about casting issues
- โ Risk: MEDIUM (may break queries)
Use Case 3: Nullability Change
Scenario: Make nullable column NOT NULL
# before_schema.json: "is_nullable": true
# after_schema.json: "is_nullable": false
scia analyze \
--before before_schema.json \
--after after_schema.json \
--format json
Output:
- โ Detects NOT NULL constraint
- โ Warns about NULL values in production
- โ Risk: MEDIUM (data quality issue)
๐ Output Formats
Markdown (Human-Readable)
scia analyze --before before_schema.json --after after_schema.json --format markdown
Output:
# Risk Assessment: HIGH
## Findings (3)
| Finding Type | Severity | Risk | Evidence |
|---|---|---|---|
| COLUMN_REMOVED | HIGH | 80 | {table: users, column: user_id} |
| COLUMN_TYPE_CHANGED | MEDIUM | 40 | {...} |
| ...| | | |
JSON (Machine-Readable)
scia analyze --before before_schema.json --after after_schema.json --format json
Output:
{
"risk_score": 120,
"classification": "HIGH",
"findings": [
{
"finding_type": "COLUMN_REMOVED",
"severity": "HIGH",
"base_risk": 80,
"evidence": {"table": "users", "column": "user_id"},
"description": "Column 'user_id' removed from table 'users'."
}
]
}
๐ง CLI Reference
Basic Command
scia analyze --before <before.json> --after <after.json> [options]
Options
| Option | Required | Example | Description |
|---|---|---|---|
--before |
โ | before.json |
Original schema (JSON, SQL, or SCHEMA.TABLE) |
--after |
โ | after.json |
Modified schema (JSON, SQL, or SCHEMA.TABLE) |
--warehouse |
โ | snowflake |
Warehouse type (required for DB mode) |
--conn-file |
โ | config.yaml |
Connection config file |
--dependency-depth |
โ | 3 |
Max depth for dependency analysis (1-10) |
--dialect |
โ | snowflake |
SQL dialect for parsing (snowflake, postgres, mysql, bigquery, databricks, redshift). Default: snowflake. Note: Only snowflake dialect is fully supported currently. |
--format |
โ | json or markdown |
Output format (default: json) |
--fail-on |
โ | HIGH |
Exit code 1 if risk meets threshold |
Exit Codes
0โ Success (risk below threshold or below--fail-on)1โ Risk matches--fail-onthreshold
Example: Use in CI/CD
# Fail CI if HIGH risk detected
scia analyze --before before.json --after after.json --fail-on HIGH
๐ก Examples
Example 1: Safe Column Addition
before.json:
[{"schema_name": "db", "table_name": "orders", "columns": [...]}]
after.json:
[{"schema_name": "db", "table_name": "orders", "columns": [..., {"column_name": "order_notes", "data_type": "VARCHAR", "is_nullable": true, "ordinal_position": 5}]}]
Command:
scia analyze --before before.json --after after.json --format markdown
Result: โ
RISK: LOW โ New nullable column is safe
Example 2: Risky Column Removal
before.json:
[{"schema_name": "db", "table_name": "users", "columns": [{"column_name": "user_id", ...}, ...]}]
after.json:
[{"schema_name": "db", "table_name": "users", "columns": [...]}] # user_id removed
Command:
scia analyze --before before.json --after after.json --format markdown
Result: โ ๏ธ RISK: HIGH โ Primary key removed, will break joins
๐ Project Structure
SCIA/
โโโ .github/copilot-instructions.md (AI agent guidance)
โโโ AI_QUICK_REFERENCE.md (Quick reference)
โโโ README.md (This file)
โ
โโโ docs/ (Documentation)
โ โโโ design.md (Architecture)
โ โโโ REQUIREMENTS.md (Functional spec)
โ โโโ FOLDER_STRUCTURE.md (Project organization)
โ
โโโ scia/ (Source code)
โ โโโ cli/main.py (Command-line interface)
โ โโโ core/ (Analysis engine)
โ โ โโโ diff.py (Schema comparison)
โ โ โโโ rules.py (Risk rules)
โ โ โโโ risk.py (Risk scoring)
โ โโโ models/ (Data models)
โ โโโ output/ (Renderers)
โ โโโ sql/ (SQL parsing)
โ
โโโ tests/ (Tests)
โ โโโ test_diff.py
โ โโโ test_rules.py
โ โโโ fixtures/ (Test data)
โ โโโ before.json
โ โโโ after.json
โ โโโ after_medium.json
โ
โโโ pyproject.toml (Package config)
๐๏ธ What SCIA Does (v0.2)
Detects:
- Column removal, type changes, nullability changes
- JOIN key breakage (High Risk)
- GROUP BY grain changes (Medium Risk)
- Downstream view breakage (Transitive impact)
Scores risk as:
- LOW (<30) โ Safe to deploy
- MEDIUM (30-69) โ Review recommended
- HIGH (โฅ70) โ Likely to break systems
Outputs:
- JSON with
impact_detail - Markdown with "Downstream Impact" tables
๐ซ What SCIA Does NOT Do
- โ Modify your schema
- โ Connect to your warehouse (uses JSON exports)
- โ Require a metadata catalog
- โ Lock you into a vendor
- โ Support dbt as a requirement (only optional enrichment)
๐ ๏ธ For Developers
Run Tests
pytest tests/
Run a Specific Test
pytest tests/test_diff.py -v
Run with Coverage
pytest tests/ --cov=scia
Develop & Install in Editable Mode
pip install -e .
๐ Documentation
- docs/design.md โ Architecture & design decisions
- docs/REQUIREMENTS.md โ Functional specification
- docs/FOLDER_STRUCTURE.md โ Project organization
- .github/copilot-instructions.md โ AI agent guidance (for developers extending SCIA)
๐ฏ Risk Scoring
๐ฏ Risk Scoring
Each change type gets a base risk score:
| Change Type | Base Risk | Why |
|---|---|---|
| Column removed | 80 | Breaks joins, aggregations |
| Type changed | 40 | May cause casting errors |
| Nullability changed | 50 | Data quality issues |
| Column added (nullable) | 0 | Safe โ won't break anything |
Total risk = Sum of all findings
- LOW (<30): Safe to deploy
- MEDIUM (30-69): Review before deploying
- HIGH (โฅ70): Likely to break downstream systems
๐ก Tips
Tip 1: Export Snowflake Schema
To get schema JSON from Snowflake:
SELECT
table_schema as schema_name,
table_name,
column_name,
data_type,
is_nullable,
ordinal_position
FROM information_schema.columns
WHERE table_schema = 'ANALYTICS'
ORDER BY table_name, ordinal_position;
Export as JSON and use with SCIA.
Tip 2: Use in CI/CD
Add to your deployment pipeline:
# GitHub Actions example
- name: Check schema changes
run: |
scia analyze --before before.json --after after.json --fail-on HIGH
# Job fails if HIGH risk detected
Tip 3: Compare Multiple Scenarios
# Scenario 1: Remove column
scia analyze --before base.json --after scenario1.json
# Scenario 2: Change type
scia analyze --before base.json --after scenario2.json
# Pick the safer approach
๐ง Troubleshooting
Connection Issues
Problem: Error: Connection failed to snowflake
Solutions:
- Verify config file exists:
ls ~/.scia/snowflake.yaml - Check credentials in config file
- Ensure account identifier is correct (format:
account.region.snowflakecomputing.com) - Use
--conn-fileto specify custom config location
Example:
# Use custom config file
scia analyze --before PROD.ANALYTICS --after DEV.ANALYTICS \
--warehouse snowflake --conn-file ~/my-config.yaml
SQL Parsing Errors
Problem: Warning: Failed to parse SQL in migration.sql
Explanation: SCIA supports CREATE TABLE, ALTER ADD/DROP/MODIFY/RENAME COLUMN. Other DDL is ignored.
What Happens: Analysis continues with schema-based rules only (no SQL-specific rules).
Supported Operations:
- โ
CREATE TABLE - โ
ALTER TABLE ADD COLUMN - โ
ALTER TABLE DROP COLUMN - โ
ALTER TABLE RENAME COLUMN - โ
ALTER TABLE ALTER COLUMN(type/nullability changes) - โ Stored procedures, triggers, constraints (ignored)
Dependency Analysis Errors
Problem: Error: max_depth must be 1-10, got 15
Solution: Use --dependency-depth with value between 1 and 10:
scia analyze --before a.json --after b.json --dependency-depth 5
Problem: Error: DB mode requires --warehouse flag
Solution: Add --warehouse when comparing database identifiers:
scia analyze --before PROD.ANALYTICS --after DEV.ANALYTICS --warehouse snowflake
Unsupported Warehouse
Problem: Error: Databricks adapter not yet implemented
Current Support:
- โ Snowflake (fully working)
- ๐๏ธ Databricks (planned for v0.3)
- ๐๏ธ PostgreSQL (planned for v0.3)
- ๐๏ธ Redshift (planned for v0.3)
Workaround: Export your schema to JSON and use JSON mode:
scia analyze --before schema.json --after modified.json
โ FAQ
Q: Can SCIA connect to my warehouse directly?
A: Yes! v0.2 supports live connections to Snowflake. Use --warehouse snowflake and configure ~/.scia/snowflake.yaml. See the Advanced Usage Guide for details.
Q: Do I need dbt?
A: No. SCIA works with plain SQL, JSON exports, and warehouse metadata.
Q: What warehouses are supported?
A: v0.2 fully supports Snowflake. Databricks, PostgreSQL, and Redshift are planned for v0.3.
Q: What if my schema has thousands of columns?
A: SCIA analyzes the diff, not absolute size. Performance should be acceptable. Use --dependency-depth 1 for faster analysis.
Q: Can I use this in production?
A: Yes! v0.2 is production-ready. Start with JSON mode for testing, then enable live warehouse connections. See docs/USAGE_V02.md for best practices.
๐ค Contributing
We welcome contributions! See .github/copilot-instructions.md for development guide.
Areas for contribution:
- Warehouse adapters (BigQuery, Databricks, PostgreSQL)
- SQL heuristics improvements
- Real-world incident patterns
- Testing edge cases
๐ License
Apache 2.0 โ See LICENSE file
๐ What's Next?
- v0.1 โ : Core schema diff, risk scoring, JSON-based analysis
- v0.2 โ : SQL migration parsing, live warehouse connectivity (Snowflake), downstream impact analysis
- v0.3 ๐๏ธ: Multi-warehouse support (Databricks, PostgreSQL, Redshift), advanced risk policies, incident pattern matching
๐ฌ Questions?
- Check docs/USAGE_V02.md for advanced v0.2 features
- See DOCS_INDEX.md for all documentation
- Read docs/FOLDER_STRUCTURE.md for project layout
- Check .github/copilot-instructions.md for architecture
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 scia_core-0.2.0.tar.gz.
File metadata
- Download URL: scia_core-0.2.0.tar.gz
- Upload date:
- Size: 45.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
625202b859a0b6898317d1bec3efe9f577e4796dc49de86dd97f10c7f87111ec
|
|
| MD5 |
3a6266355ee857c9b60241267e349444
|
|
| BLAKE2b-256 |
8dc7383edb560c0e99ef4196fe311dd4642cfd0e387770b6a2b62e0dcb5f65c1
|
File details
Details for the file scia_core-0.2.0-py3-none-any.whl.
File metadata
- Download URL: scia_core-0.2.0-py3-none-any.whl
- Upload date:
- Size: 41.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
de7aebf7d0a6d1ed1f726f0fe2e5474c1af8f15a13dcea309c810a746869f506
|
|
| MD5 |
2dde6c8b0f8c05aa34be4a0fc1051cb8
|
|
| BLAKE2b-256 |
ef4f55fbc41787ce908ac33cb536bcdd57b96fc1a04002c74875e83ce583d0a3
|