sql-glider 0.1.23__tar.gz → 0.1.25__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sql_glider-0.1.23 → sql_glider-0.1.25}/CLAUDE.md +9 -0
- sql_glider-0.1.23/README.md → sql_glider-0.1.25/PKG-INFO +83 -1
- sql_glider-0.1.23/PKG-INFO → sql_glider-0.1.25/README.md +49 -33
- {sql_glider-0.1.23 → sql_glider-0.1.25}/docs/docs/graph-lineage.md +59 -1
- sql_glider-0.1.25/docs/docs/static/plotly-dash-example.png +0 -0
- sql_glider-0.1.25/examples/plotly_viewer.py +118 -0
- sql_glider-0.1.25/graph.json +5319 -0
- sql_glider-0.1.25/lineage.json +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/pyproject.toml +3 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/_version.py +2 -2
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/cli.py +37 -13
- sql_glider-0.1.25/src/sqlglider/graph/diagram_formatters.py +738 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/graph/test_diagram_formatters.py +371 -1
- {sql_glider-0.1.23 → sql_glider-0.1.25}/uv.lock +146 -1
- sql_glider-0.1.23/src/sqlglider/graph/diagram_formatters.py +0 -330
- {sql_glider-0.1.23 → sql_glider-0.1.25}/.github/workflows/ci.yml +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/.github/workflows/docs.yml +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/.github/workflows/publish.yml +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/.gitignore +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/.python-version +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/ARCHITECTURE.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/LICENSE +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/docs/.github/workflows/docs.yml +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/docs/docs/catalogs.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/docs/docs/index.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/docs/docs/static/sqlglider-logo-transparent.png +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/docs/docs/templating.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/docs/zensical.toml +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2025-12-05-column-level-lineage.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2025-12-05-reverse-lineage.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2025-12-06-config-file-support.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2025-12-06-graph-lineage.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2025-12-06-unify-single-multi-query.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2025-12-07-sample-data-model.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2025-12-07-sql-templating.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2025-12-08-tables-command.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2025-12-09-graph-query-paths.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2025-12-13-dissect-command.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2025-12-14-tables-pull-command.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2026-01-25-fix-union-lineage-chain.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2026-01-26-file-scoped-schema-context.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2026-01-28-sparksql-table-extraction.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2026-01-29-no-star-flag.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2026-01-29-resolve-schema.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2026-01-29-schema-pruning-optimization.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2026-01-29-tables-scrape-command.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/plans/2026-02-02-diagram-output-formats.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/README.md +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/business/expire_dim_customer.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/business/load_fact_orders.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/business/load_fact_payments.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/business/merge_dim_customer.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/business/merge_dim_product.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/business/update_dim_customer_metrics.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/complex/conditional_merge.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/complex/cte_insert.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/complex/multi_table_transform.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/ddl/dim_customer.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/ddl/dim_product.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/ddl/fact_orders.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/ddl/fact_payments.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/ddl/raw_addresses.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/ddl/raw_customers.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/ddl/raw_order_items.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/ddl/raw_orders.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/ddl/raw_payments.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/ddl/raw_products.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/ddl/stg_customers.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/ddl/stg_orders.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/ddl/stg_payments.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/ddl/stg_products.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/incremental/incr_fact_orders.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/incremental/incr_fact_payments.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/incremental/incr_pres_sales_summary.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/maintenance/delete_expired_customers.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/maintenance/update_product_status.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/presentation/load_pres_customer_360.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/presentation/load_pres_customer_cohort.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/presentation/load_pres_product_performance.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/presentation/load_pres_sales_summary.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/staging/load_stg_customers.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/staging/load_stg_orders.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/staging/load_stg_payments.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sample_data_model/staging/load_stg_products.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/sqlglider.toml.example +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/__init__.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/catalog/__init__.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/catalog/base.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/catalog/databricks.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/catalog/registry.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/dissection/__init__.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/dissection/analyzer.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/dissection/formatters.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/dissection/models.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/global_models.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/graph/__init__.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/graph/builder.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/graph/formatters.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/graph/merge.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/graph/models.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/graph/query.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/graph/serialization.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/lineage/__init__.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/lineage/analyzer.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/lineage/formatters.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/schema/__init__.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/schema/extractor.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/templating/__init__.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/templating/base.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/templating/jinja.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/templating/registry.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/templating/variables.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/utils/__init__.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/utils/config.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/utils/file_utils.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/src/sqlglider/utils/schema.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/__init__.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/multi_file_queries/analytics_pipeline.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/multi_file_queries/analytics_pipeline_union_merge.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/multi_file_queries/customers.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/multi_file_queries/orders.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/multi_file_queries/reports.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/multi_file_queries/view_based_merge.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/original_queries/test_cte.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/original_queries/test_cte_query.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/original_queries/test_cte_view_star.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/original_queries/test_generated_column_query.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/original_queries/test_multi.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/original_queries/test_multi_query.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/original_queries/test_single_query.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/original_queries/test_subquery.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/original_queries/test_tables.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/original_queries/test_view.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/original_queries/test_view_window_cte.sql +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/fixtures/sample_manifest.csv +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/__init__.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/catalog/__init__.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/catalog/test_base.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/catalog/test_databricks.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/catalog/test_registry.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/dissection/__init__.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/dissection/test_analyzer.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/dissection/test_formatters.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/dissection/test_models.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/graph/__init__.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/graph/test_builder.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/graph/test_formatters.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/graph/test_merge.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/graph/test_models.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/graph/test_query.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/graph/test_serialization.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/lineage/__init__.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/lineage/test_analyzer.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/lineage/test_formatters.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/schema/__init__.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/schema/test_extractor.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/templating/__init__.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/templating/test_base.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/templating/test_jinja.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/templating/test_registry.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/templating/test_variables.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/test_cli.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/utils/__init__.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/utils/test_config.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/utils/test_file_utils.py +0 -0
- {sql_glider-0.1.23 → sql_glider-0.1.25}/tests/sqlglider/utils/test_schema.py +0 -0
|
@@ -276,17 +276,26 @@ uv run sqlglider graph query graph.json --upstream orders.total -f mermaid
|
|
|
276
276
|
# Query with DOT (Graphviz) diagram output
|
|
277
277
|
uv run sqlglider graph query graph.json --downstream customers.id -f dot
|
|
278
278
|
|
|
279
|
+
# Query with Plotly JSON output (for Dash/Plotly apps)
|
|
280
|
+
uv run sqlglider graph query graph.json --upstream orders.total -f plotly
|
|
281
|
+
|
|
279
282
|
# Visualize entire graph as Mermaid diagram
|
|
280
283
|
uv run sqlglider graph visualize graph.json
|
|
281
284
|
|
|
282
285
|
# Visualize entire graph as DOT diagram
|
|
283
286
|
uv run sqlglider graph visualize graph.json -f dot
|
|
284
287
|
|
|
288
|
+
# Visualize entire graph as Plotly JSON
|
|
289
|
+
uv run sqlglider graph visualize graph.json -f plotly
|
|
290
|
+
|
|
285
291
|
# Save diagram to file
|
|
286
292
|
uv run sqlglider graph visualize graph.json -o lineage.mmd
|
|
287
293
|
uv run sqlglider graph visualize graph.json -f dot -o lineage.dot
|
|
294
|
+
uv run sqlglider graph visualize graph.json -f plotly -o lineage.json
|
|
288
295
|
```
|
|
289
296
|
|
|
297
|
+
**Note:** Plotly output requires the optional dependency: `pip install sql-glider[plotly]`
|
|
298
|
+
|
|
290
299
|
### SQL Templating
|
|
291
300
|
|
|
292
301
|
SQL Glider supports Jinja2 templating for SQL files. This allows you to use variables, conditionals, and loops in your SQL before analysis.
|
|
@@ -1,3 +1,37 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sql-glider
|
|
3
|
+
Version: 0.1.25
|
|
4
|
+
Summary: SQL Utility Toolkit for better understanding, use, and governance of your queries in a native environment.
|
|
5
|
+
Project-URL: Homepage, https://github.com/rycowhi/sql-glider/
|
|
6
|
+
Project-URL: Repository, https://github.com/rycowhi/sql-glider/
|
|
7
|
+
Project-URL: Documentation, https://github.com/rycowhi/sql-glider/
|
|
8
|
+
Project-URL: Issues, https://github.com/rycowhi/sql-glider/issues
|
|
9
|
+
Author-email: Ryan Whitcomb <ryankwhitcomb@gmail.com>
|
|
10
|
+
License-Expression: Apache-2.0
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: data-governance,data-lineage,lineage,sql,sqlglot
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Programming Language :: SQL
|
|
19
|
+
Classifier: Topic :: Database
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Requires-Dist: jinja2>=3.0.0
|
|
24
|
+
Requires-Dist: pydantic>=2.0.0
|
|
25
|
+
Requires-Dist: rich>=13.0.0
|
|
26
|
+
Requires-Dist: rustworkx>=0.15.0
|
|
27
|
+
Requires-Dist: sqlglot[rs]>=25.0.0
|
|
28
|
+
Requires-Dist: typer>=0.9.0
|
|
29
|
+
Provides-Extra: databricks
|
|
30
|
+
Requires-Dist: databricks-sdk>=0.20.0; extra == 'databricks'
|
|
31
|
+
Provides-Extra: plotly
|
|
32
|
+
Requires-Dist: plotly>=5.0.0; extra == 'plotly'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
1
35
|
# SQL Glider
|
|
2
36
|
|
|
3
37
|

|
|
@@ -388,12 +422,33 @@ uv run sqlglider graph query graph.json --upstream orders.customer_id -f mermaid
|
|
|
388
422
|
# Query with DOT (Graphviz) diagram output
|
|
389
423
|
uv run sqlglider graph query graph.json --downstream customers.id -f dot
|
|
390
424
|
|
|
425
|
+
# Query with Plotly JSON output (for interactive visualization)
|
|
426
|
+
uv run sqlglider graph query graph.json --upstream orders.customer_id -f plotly
|
|
427
|
+
|
|
391
428
|
# Visualize entire graph as a diagram
|
|
392
429
|
uv run sqlglider graph visualize graph.json # Mermaid (default)
|
|
393
430
|
uv run sqlglider graph visualize graph.json -f dot # DOT/Graphviz
|
|
431
|
+
uv run sqlglider graph visualize graph.json -f plotly # Plotly JSON
|
|
394
432
|
uv run sqlglider graph visualize graph.json -o lineage.mmd # Save to file
|
|
395
433
|
```
|
|
396
434
|
|
|
435
|
+
> **Note:** Plotly output requires an optional dependency. Install with: `pip install sql-glider[plotly]`
|
|
436
|
+
|
|
437
|
+
The Plotly JSON output can be loaded into Plotly/Dash applications for interactive visualization:
|
|
438
|
+
|
|
439
|
+
```python
|
|
440
|
+
import plotly.io as pio
|
|
441
|
+
from dash import Dash, dcc, html
|
|
442
|
+
|
|
443
|
+
# Load the JSON output
|
|
444
|
+
with open("lineage.json") as f:
|
|
445
|
+
fig = pio.from_json(f.read())
|
|
446
|
+
|
|
447
|
+
# Use in a Dash app
|
|
448
|
+
app = Dash(__name__)
|
|
449
|
+
app.layout = html.Div([dcc.Graph(figure=fig)])
|
|
450
|
+
```
|
|
451
|
+
|
|
397
452
|
**Example Upstream Query Output:**
|
|
398
453
|
```
|
|
399
454
|
Sources for 'order_totals.total'
|
|
@@ -679,12 +734,24 @@ Arguments:
|
|
|
679
734
|
Options:
|
|
680
735
|
--upstream, -u Find source columns for this column [optional]
|
|
681
736
|
--downstream, -d Find affected columns for this source [optional]
|
|
682
|
-
--output-format, -f Output format: 'text', 'json', or '
|
|
737
|
+
--output-format, -f Output format: 'text', 'json', 'csv', 'mermaid', 'mermaid-markdown', 'dot', or 'plotly' [default: text]
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
```
|
|
741
|
+
sqlglider graph visualize <graph_file> [OPTIONS]
|
|
742
|
+
|
|
743
|
+
Arguments:
|
|
744
|
+
graph_file Path to graph JSON file [required]
|
|
745
|
+
|
|
746
|
+
Options:
|
|
747
|
+
--output-format, -f Diagram format: 'mermaid', 'mermaid-markdown', 'dot', or 'plotly' [default: mermaid]
|
|
748
|
+
--output-file, -o Write diagram to file instead of stdout [optional]
|
|
683
749
|
```
|
|
684
750
|
|
|
685
751
|
**Notes:**
|
|
686
752
|
- `--upstream` and `--downstream` are mutually exclusive. Use one or the other.
|
|
687
753
|
- Graph queries are case-insensitive for column matching.
|
|
754
|
+
- Plotly output requires optional dependency: `pip install sql-glider[plotly]`
|
|
688
755
|
|
|
689
756
|
## Output Formats
|
|
690
757
|
|
|
@@ -889,6 +956,21 @@ UV_PUBLISH_TOKEN=pypi-...
|
|
|
889
956
|
- **pydantic:** Data validation and serialization
|
|
890
957
|
- **rustworkx:** High-performance graph library for cross-file lineage analysis
|
|
891
958
|
|
|
959
|
+
### Optional Dependencies
|
|
960
|
+
|
|
961
|
+
Install optional features with extras:
|
|
962
|
+
|
|
963
|
+
```bash
|
|
964
|
+
# Databricks catalog integration
|
|
965
|
+
pip install sql-glider[databricks]
|
|
966
|
+
|
|
967
|
+
# Plotly interactive visualization
|
|
968
|
+
pip install sql-glider[plotly]
|
|
969
|
+
|
|
970
|
+
# Install multiple extras
|
|
971
|
+
pip install sql-glider[databricks,plotly]
|
|
972
|
+
```
|
|
973
|
+
|
|
892
974
|
## References
|
|
893
975
|
|
|
894
976
|
- [SQLGlot Documentation](https://sqlglot.com/)
|
|
@@ -1,35 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: sql-glider
|
|
3
|
-
Version: 0.1.23
|
|
4
|
-
Summary: SQL Utility Toolkit for better understanding, use, and governance of your queries in a native environment.
|
|
5
|
-
Project-URL: Homepage, https://github.com/rycowhi/sql-glider/
|
|
6
|
-
Project-URL: Repository, https://github.com/rycowhi/sql-glider/
|
|
7
|
-
Project-URL: Documentation, https://github.com/rycowhi/sql-glider/
|
|
8
|
-
Project-URL: Issues, https://github.com/rycowhi/sql-glider/issues
|
|
9
|
-
Author-email: Ryan Whitcomb <ryankwhitcomb@gmail.com>
|
|
10
|
-
License-Expression: Apache-2.0
|
|
11
|
-
License-File: LICENSE
|
|
12
|
-
Keywords: data-governance,data-lineage,lineage,sql,sqlglot
|
|
13
|
-
Classifier: Development Status :: 3 - Alpha
|
|
14
|
-
Classifier: Intended Audience :: Developers
|
|
15
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
16
|
-
Classifier: Operating System :: OS Independent
|
|
17
|
-
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
-
Classifier: Programming Language :: SQL
|
|
19
|
-
Classifier: Topic :: Database
|
|
20
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
-
Classifier: Typing :: Typed
|
|
22
|
-
Requires-Python: >=3.11
|
|
23
|
-
Requires-Dist: jinja2>=3.0.0
|
|
24
|
-
Requires-Dist: pydantic>=2.0.0
|
|
25
|
-
Requires-Dist: rich>=13.0.0
|
|
26
|
-
Requires-Dist: rustworkx>=0.15.0
|
|
27
|
-
Requires-Dist: sqlglot[rs]>=25.0.0
|
|
28
|
-
Requires-Dist: typer>=0.9.0
|
|
29
|
-
Provides-Extra: databricks
|
|
30
|
-
Requires-Dist: databricks-sdk>=0.20.0; extra == 'databricks'
|
|
31
|
-
Description-Content-Type: text/markdown
|
|
32
|
-
|
|
33
1
|
# SQL Glider
|
|
34
2
|
|
|
35
3
|

|
|
@@ -420,12 +388,33 @@ uv run sqlglider graph query graph.json --upstream orders.customer_id -f mermaid
|
|
|
420
388
|
# Query with DOT (Graphviz) diagram output
|
|
421
389
|
uv run sqlglider graph query graph.json --downstream customers.id -f dot
|
|
422
390
|
|
|
391
|
+
# Query with Plotly JSON output (for interactive visualization)
|
|
392
|
+
uv run sqlglider graph query graph.json --upstream orders.customer_id -f plotly
|
|
393
|
+
|
|
423
394
|
# Visualize entire graph as a diagram
|
|
424
395
|
uv run sqlglider graph visualize graph.json # Mermaid (default)
|
|
425
396
|
uv run sqlglider graph visualize graph.json -f dot # DOT/Graphviz
|
|
397
|
+
uv run sqlglider graph visualize graph.json -f plotly # Plotly JSON
|
|
426
398
|
uv run sqlglider graph visualize graph.json -o lineage.mmd # Save to file
|
|
427
399
|
```
|
|
428
400
|
|
|
401
|
+
> **Note:** Plotly output requires an optional dependency. Install with: `pip install sql-glider[plotly]`
|
|
402
|
+
|
|
403
|
+
The Plotly JSON output can be loaded into Plotly/Dash applications for interactive visualization:
|
|
404
|
+
|
|
405
|
+
```python
|
|
406
|
+
import plotly.io as pio
|
|
407
|
+
from dash import Dash, dcc, html
|
|
408
|
+
|
|
409
|
+
# Load the JSON output
|
|
410
|
+
with open("lineage.json") as f:
|
|
411
|
+
fig = pio.from_json(f.read())
|
|
412
|
+
|
|
413
|
+
# Use in a Dash app
|
|
414
|
+
app = Dash(__name__)
|
|
415
|
+
app.layout = html.Div([dcc.Graph(figure=fig)])
|
|
416
|
+
```
|
|
417
|
+
|
|
429
418
|
**Example Upstream Query Output:**
|
|
430
419
|
```
|
|
431
420
|
Sources for 'order_totals.total'
|
|
@@ -711,12 +700,24 @@ Arguments:
|
|
|
711
700
|
Options:
|
|
712
701
|
--upstream, -u Find source columns for this column [optional]
|
|
713
702
|
--downstream, -d Find affected columns for this source [optional]
|
|
714
|
-
--output-format, -f Output format: 'text', 'json', or '
|
|
703
|
+
--output-format, -f Output format: 'text', 'json', 'csv', 'mermaid', 'mermaid-markdown', 'dot', or 'plotly' [default: text]
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
```
|
|
707
|
+
sqlglider graph visualize <graph_file> [OPTIONS]
|
|
708
|
+
|
|
709
|
+
Arguments:
|
|
710
|
+
graph_file Path to graph JSON file [required]
|
|
711
|
+
|
|
712
|
+
Options:
|
|
713
|
+
--output-format, -f Diagram format: 'mermaid', 'mermaid-markdown', 'dot', or 'plotly' [default: mermaid]
|
|
714
|
+
--output-file, -o Write diagram to file instead of stdout [optional]
|
|
715
715
|
```
|
|
716
716
|
|
|
717
717
|
**Notes:**
|
|
718
718
|
- `--upstream` and `--downstream` are mutually exclusive. Use one or the other.
|
|
719
719
|
- Graph queries are case-insensitive for column matching.
|
|
720
|
+
- Plotly output requires optional dependency: `pip install sql-glider[plotly]`
|
|
720
721
|
|
|
721
722
|
## Output Formats
|
|
722
723
|
|
|
@@ -921,6 +922,21 @@ UV_PUBLISH_TOKEN=pypi-...
|
|
|
921
922
|
- **pydantic:** Data validation and serialization
|
|
922
923
|
- **rustworkx:** High-performance graph library for cross-file lineage analysis
|
|
923
924
|
|
|
925
|
+
### Optional Dependencies
|
|
926
|
+
|
|
927
|
+
Install optional features with extras:
|
|
928
|
+
|
|
929
|
+
```bash
|
|
930
|
+
# Databricks catalog integration
|
|
931
|
+
pip install sql-glider[databricks]
|
|
932
|
+
|
|
933
|
+
# Plotly interactive visualization
|
|
934
|
+
pip install sql-glider[plotly]
|
|
935
|
+
|
|
936
|
+
# Install multiple extras
|
|
937
|
+
pip install sql-glider[databricks,plotly]
|
|
938
|
+
```
|
|
939
|
+
|
|
924
940
|
## References
|
|
925
941
|
|
|
926
942
|
- [SQLGlot Documentation](https://sqlglot.com/)
|
|
@@ -221,7 +221,7 @@ Each entry in `columns` tells you:
|
|
|
221
221
|
|
|
222
222
|
## Visualizing Lineage
|
|
223
223
|
|
|
224
|
-
SQL Glider can generate diagrams from lineage graphs in [Mermaid](https://mermaid.js.org/)
|
|
224
|
+
SQL Glider can generate diagrams from lineage graphs in [Mermaid](https://mermaid.js.org/), [DOT (Graphviz)](https://graphviz.org/doc/info/lang.html), and [Plotly](https://plotly.com/python/) formats. Mermaid and DOT are text-based diagram languages that render in many tools — Mermaid works natively in GitHub Markdown, GitLab, Notion, and more; DOT can be rendered with Graphviz into SVG, PNG, or PDF. Plotly outputs JSON that can be loaded into interactive Plotly/Dash applications.
|
|
225
225
|
|
|
226
226
|
### Visualize an Entire Graph
|
|
227
227
|
|
|
@@ -234,9 +234,13 @@ sqlglider graph visualize graph.json
|
|
|
234
234
|
# DOT (Graphviz)
|
|
235
235
|
sqlglider graph visualize graph.json -f dot
|
|
236
236
|
|
|
237
|
+
# Plotly JSON (for interactive visualization)
|
|
238
|
+
sqlglider graph visualize graph.json -f plotly
|
|
239
|
+
|
|
237
240
|
# Save to file
|
|
238
241
|
sqlglider graph visualize graph.json -o lineage.mmd
|
|
239
242
|
sqlglider graph visualize graph.json -f dot -o lineage.dot
|
|
243
|
+
sqlglider graph visualize graph.json -f plotly -o lineage.json
|
|
240
244
|
```
|
|
241
245
|
|
|
242
246
|
### Diagram Output from Queries
|
|
@@ -249,6 +253,9 @@ sqlglider graph query graph.json --upstream total_spent -f mermaid
|
|
|
249
253
|
|
|
250
254
|
# DOT diagram of downstream impact
|
|
251
255
|
sqlglider graph query graph.json --downstream orders.order_total -f dot
|
|
256
|
+
|
|
257
|
+
# Plotly JSON for interactive exploration
|
|
258
|
+
sqlglider graph query graph.json --upstream total_spent -f plotly
|
|
252
259
|
```
|
|
253
260
|
|
|
254
261
|
Query diagrams include color-coded nodes and a legend:
|
|
@@ -308,6 +315,51 @@ sqlglider graph visualize graph.json -f mermaid-markdown -o lineage.md
|
|
|
308
315
|
|
|
309
316
|
This produces output with the `` ```mermaid `` fence included, so the diagram renders automatically when viewed in GitHub, GitLab, or any markdown tool with Mermaid support.
|
|
310
317
|
|
|
318
|
+
### Plotly Interactive Visualization
|
|
319
|
+
|
|
320
|
+
The `plotly` format outputs a JSON figure specification that can be loaded into [Plotly](https://plotly.com/python/) or [Dash](https://dash.plotly.com/) applications for interactive visualization with zooming, panning, and hover details.
|
|
321
|
+
|
|
322
|
+
!!! warning "Optional Dependency"
|
|
323
|
+
|
|
324
|
+
Plotly output requires an optional dependency. Install it with:
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
pip install sql-glider[plotly]
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**Example usage with Dash:**
|
|
331
|
+
|
|
332
|
+
```python
|
|
333
|
+
import plotly.io as pio
|
|
334
|
+
from dash import Dash, dcc, html
|
|
335
|
+
|
|
336
|
+
# Load the JSON output from sqlglider
|
|
337
|
+
with open("lineage.json") as f:
|
|
338
|
+
fig = pio.from_json(f.read())
|
|
339
|
+
|
|
340
|
+
# Create an interactive Dash app
|
|
341
|
+
app = Dash(__name__)
|
|
342
|
+
app.layout = html.Div([
|
|
343
|
+
html.H1("Lineage Graph"),
|
|
344
|
+
dcc.Graph(figure=fig, style={"height": "80vh"})
|
|
345
|
+
])
|
|
346
|
+
|
|
347
|
+
if __name__ == "__main__":
|
|
348
|
+
app.run(debug=True)
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
The Plotly output uses the same color scheme as Mermaid and DOT diagrams:
|
|
352
|
+
|
|
353
|
+
| Color | Meaning |
|
|
354
|
+
|--------|---------|
|
|
355
|
+
| Amber | The queried column |
|
|
356
|
+
| Teal | Root node (no upstream dependencies) |
|
|
357
|
+
| Violet | Leaf node (no downstream consumers) |
|
|
358
|
+
|
|
359
|
+
See an example of a plot loaded into Dash below:
|
|
360
|
+
|
|
361
|
+

|
|
362
|
+
|
|
311
363
|
### Rendering Diagrams
|
|
312
364
|
|
|
313
365
|
**Mermaid:**
|
|
@@ -322,6 +374,12 @@ This produces output with the `` ```mermaid `` fence included, so the diagram re
|
|
|
322
374
|
- Use `-Tsvg` for scalable vector output
|
|
323
375
|
- Many IDEs have Graphviz preview extensions
|
|
324
376
|
|
|
377
|
+
**Plotly:**
|
|
378
|
+
|
|
379
|
+
- Load the JSON into any Plotly-compatible environment (Python, Dash, Jupyter notebooks)
|
|
380
|
+
- SQL Glider includes a viewer script: `python examples/plotly_viewer.py lineage.json`
|
|
381
|
+
- Export to static images with `fig.write_image("lineage.png")`
|
|
382
|
+
|
|
325
383
|
## Building Graphs from Multiple Sources
|
|
326
384
|
|
|
327
385
|
### Explicit File List
|
|
Binary file
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Simple Dash app to view SQL Glider Plotly lineage output.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
# graph visualize has -o flag for file output
|
|
6
|
+
uv run sqlglider graph visualize graph.json -f plotly -o lineage.json
|
|
7
|
+
uv run python examples/plotly_viewer.py lineage.json
|
|
8
|
+
|
|
9
|
+
# graph query needs shell redirect - use PowerShell on Windows for proper encoding
|
|
10
|
+
uv run sqlglider graph query graph.json --upstream orders.total -f plotly | Out-File -Encoding utf8 lineage.json
|
|
11
|
+
uv run python examples/plotly_viewer.py lineage.json
|
|
12
|
+
|
|
13
|
+
# On Unix/macOS:
|
|
14
|
+
sqlglider graph query graph.json --upstream orders.total -f plotly > lineage.json
|
|
15
|
+
python examples/plotly_viewer.py lineage.json
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
import sys
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
import dash
|
|
24
|
+
from dash import dcc, html
|
|
25
|
+
except ImportError:
|
|
26
|
+
print("Error: Dash is required. Install with: pip install dash", file=sys.stderr)
|
|
27
|
+
sys.exit(1)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def load_figure(source: str | Path | None = None) -> dict:
|
|
31
|
+
"""Load Plotly figure from file or stdin."""
|
|
32
|
+
if source is None or source == "-":
|
|
33
|
+
# Read from stdin
|
|
34
|
+
if sys.stdin.isatty():
|
|
35
|
+
print("Usage: python plotly_viewer.py <lineage.json>", file=sys.stderr)
|
|
36
|
+
print(
|
|
37
|
+
" or: sqlglider graph visualize graph.json -f plotly | python plotly_viewer.py",
|
|
38
|
+
file=sys.stderr,
|
|
39
|
+
)
|
|
40
|
+
sys.exit(1)
|
|
41
|
+
content = sys.stdin.read()
|
|
42
|
+
if not content.strip():
|
|
43
|
+
print("Error: No input received from stdin", file=sys.stderr)
|
|
44
|
+
print("Note: On Windows, piping may not work reliably.", file=sys.stderr)
|
|
45
|
+
print(
|
|
46
|
+
"Try: sqlglider graph query ... -f plotly -o output.json",
|
|
47
|
+
file=sys.stderr,
|
|
48
|
+
)
|
|
49
|
+
print("Then: python plotly_viewer.py output.json", file=sys.stderr)
|
|
50
|
+
sys.exit(1)
|
|
51
|
+
else:
|
|
52
|
+
path = Path(source)
|
|
53
|
+
if not path.exists():
|
|
54
|
+
print(f"Error: File not found: {path}", file=sys.stderr)
|
|
55
|
+
sys.exit(1)
|
|
56
|
+
# Try multiple encodings - Windows redirect can create UTF-16 files
|
|
57
|
+
for encoding in ["utf-8", "utf-16", "utf-8-sig"]:
|
|
58
|
+
try:
|
|
59
|
+
content = path.read_text(encoding=encoding)
|
|
60
|
+
break
|
|
61
|
+
except UnicodeDecodeError:
|
|
62
|
+
continue
|
|
63
|
+
else:
|
|
64
|
+
print(
|
|
65
|
+
"Error: Could not decode file with UTF-8 or UTF-16 encoding",
|
|
66
|
+
file=sys.stderr,
|
|
67
|
+
)
|
|
68
|
+
sys.exit(1)
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
return json.loads(content)
|
|
72
|
+
except json.JSONDecodeError as e:
|
|
73
|
+
print(f"Error: Invalid JSON: {e}", file=sys.stderr)
|
|
74
|
+
if len(content) < 200:
|
|
75
|
+
print(f"Content received: {content!r}", file=sys.stderr)
|
|
76
|
+
else:
|
|
77
|
+
print(f"Content starts with: {content[:200]!r}...", file=sys.stderr)
|
|
78
|
+
sys.exit(1)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def create_app(figure: dict) -> dash.Dash:
|
|
82
|
+
"""Create Dash app with the lineage graph."""
|
|
83
|
+
app = dash.Dash(__name__)
|
|
84
|
+
|
|
85
|
+
title = figure.get("layout", {}).get("title", {}).get("text", "Lineage Graph")
|
|
86
|
+
|
|
87
|
+
app.layout = html.Div(
|
|
88
|
+
[
|
|
89
|
+
html.H1(title, style={"textAlign": "center", "fontFamily": "sans-serif"}),
|
|
90
|
+
dcc.Graph(
|
|
91
|
+
id="lineage-graph",
|
|
92
|
+
figure=figure,
|
|
93
|
+
style={"height": "85vh"},
|
|
94
|
+
config={
|
|
95
|
+
"displayModeBar": True,
|
|
96
|
+
"scrollZoom": True,
|
|
97
|
+
"modeBarButtonsToAdd": ["select2d", "lasso2d"],
|
|
98
|
+
},
|
|
99
|
+
),
|
|
100
|
+
],
|
|
101
|
+
style={"padding": "20px"},
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
return app
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def main():
|
|
108
|
+
source = sys.argv[1] if len(sys.argv) > 1 else None
|
|
109
|
+
figure = load_figure(source)
|
|
110
|
+
app = create_app(figure)
|
|
111
|
+
|
|
112
|
+
print("Starting Dash server at http://127.0.0.1:8050")
|
|
113
|
+
print("Press Ctrl+C to stop")
|
|
114
|
+
app.run(debug=True, host="127.0.0.1", port=8050)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
if __name__ == "__main__":
|
|
118
|
+
main()
|