sql-glider 0.1.21__tar.gz → 0.1.24__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.
Files changed (163) hide show
  1. {sql_glider-0.1.21 → sql_glider-0.1.24}/CLAUDE.md +9 -0
  2. sql_glider-0.1.21/README.md → sql_glider-0.1.24/PKG-INFO +83 -1
  3. sql_glider-0.1.21/PKG-INFO → sql_glider-0.1.24/README.md +49 -33
  4. {sql_glider-0.1.21 → sql_glider-0.1.24}/docs/docs/graph-lineage.md +55 -1
  5. {sql_glider-0.1.21 → sql_glider-0.1.24}/docs/zensical.toml +6 -4
  6. sql_glider-0.1.24/examples/plotly_viewer.py +109 -0
  7. {sql_glider-0.1.21 → sql_glider-0.1.24}/pyproject.toml +3 -0
  8. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/_version.py +2 -2
  9. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/cli.py +46 -17
  10. sql_glider-0.1.24/src/sqlglider/graph/diagram_formatters.py +658 -0
  11. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/graph/test_diagram_formatters.py +287 -1
  12. {sql_glider-0.1.21 → sql_glider-0.1.24}/uv.lock +146 -1
  13. sql_glider-0.1.21/src/sqlglider/graph/diagram_formatters.py +0 -330
  14. {sql_glider-0.1.21 → sql_glider-0.1.24}/.github/workflows/ci.yml +0 -0
  15. {sql_glider-0.1.21 → sql_glider-0.1.24}/.github/workflows/docs.yml +0 -0
  16. {sql_glider-0.1.21 → sql_glider-0.1.24}/.github/workflows/publish.yml +0 -0
  17. {sql_glider-0.1.21 → sql_glider-0.1.24}/.gitignore +0 -0
  18. {sql_glider-0.1.21 → sql_glider-0.1.24}/.python-version +0 -0
  19. {sql_glider-0.1.21 → sql_glider-0.1.24}/ARCHITECTURE.md +0 -0
  20. {sql_glider-0.1.21 → sql_glider-0.1.24}/LICENSE +0 -0
  21. {sql_glider-0.1.21 → sql_glider-0.1.24}/docs/.github/workflows/docs.yml +0 -0
  22. {sql_glider-0.1.21 → sql_glider-0.1.24}/docs/docs/catalogs.md +0 -0
  23. {sql_glider-0.1.21 → sql_glider-0.1.24}/docs/docs/index.md +0 -0
  24. {sql_glider-0.1.21 → sql_glider-0.1.24}/docs/docs/static/sqlglider-logo-transparent.png +0 -0
  25. {sql_glider-0.1.21 → sql_glider-0.1.24}/docs/docs/templating.md +0 -0
  26. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2025-12-05-column-level-lineage.md +0 -0
  27. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2025-12-05-reverse-lineage.md +0 -0
  28. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2025-12-06-config-file-support.md +0 -0
  29. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2025-12-06-graph-lineage.md +0 -0
  30. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2025-12-06-unify-single-multi-query.md +0 -0
  31. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2025-12-07-sample-data-model.md +0 -0
  32. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2025-12-07-sql-templating.md +0 -0
  33. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2025-12-08-tables-command.md +0 -0
  34. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2025-12-09-graph-query-paths.md +0 -0
  35. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2025-12-13-dissect-command.md +0 -0
  36. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2025-12-14-tables-pull-command.md +0 -0
  37. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2026-01-25-fix-union-lineage-chain.md +0 -0
  38. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2026-01-26-file-scoped-schema-context.md +0 -0
  39. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2026-01-28-sparksql-table-extraction.md +0 -0
  40. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2026-01-29-no-star-flag.md +0 -0
  41. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2026-01-29-resolve-schema.md +0 -0
  42. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2026-01-29-schema-pruning-optimization.md +0 -0
  43. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2026-01-29-tables-scrape-command.md +0 -0
  44. {sql_glider-0.1.21 → sql_glider-0.1.24}/plans/2026-02-02-diagram-output-formats.md +0 -0
  45. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/README.md +0 -0
  46. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/business/expire_dim_customer.sql +0 -0
  47. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/business/load_fact_orders.sql +0 -0
  48. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/business/load_fact_payments.sql +0 -0
  49. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/business/merge_dim_customer.sql +0 -0
  50. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/business/merge_dim_product.sql +0 -0
  51. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/business/update_dim_customer_metrics.sql +0 -0
  52. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/complex/conditional_merge.sql +0 -0
  53. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/complex/cte_insert.sql +0 -0
  54. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/complex/multi_table_transform.sql +0 -0
  55. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/ddl/dim_customer.sql +0 -0
  56. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/ddl/dim_product.sql +0 -0
  57. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/ddl/fact_orders.sql +0 -0
  58. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/ddl/fact_payments.sql +0 -0
  59. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/ddl/raw_addresses.sql +0 -0
  60. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/ddl/raw_customers.sql +0 -0
  61. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/ddl/raw_order_items.sql +0 -0
  62. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/ddl/raw_orders.sql +0 -0
  63. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/ddl/raw_payments.sql +0 -0
  64. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/ddl/raw_products.sql +0 -0
  65. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/ddl/stg_customers.sql +0 -0
  66. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/ddl/stg_orders.sql +0 -0
  67. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/ddl/stg_payments.sql +0 -0
  68. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/ddl/stg_products.sql +0 -0
  69. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/incremental/incr_fact_orders.sql +0 -0
  70. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/incremental/incr_fact_payments.sql +0 -0
  71. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/incremental/incr_pres_sales_summary.sql +0 -0
  72. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/maintenance/delete_expired_customers.sql +0 -0
  73. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/maintenance/update_product_status.sql +0 -0
  74. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/presentation/load_pres_customer_360.sql +0 -0
  75. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/presentation/load_pres_customer_cohort.sql +0 -0
  76. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/presentation/load_pres_product_performance.sql +0 -0
  77. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/presentation/load_pres_sales_summary.sql +0 -0
  78. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/staging/load_stg_customers.sql +0 -0
  79. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/staging/load_stg_orders.sql +0 -0
  80. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/staging/load_stg_payments.sql +0 -0
  81. {sql_glider-0.1.21 → sql_glider-0.1.24}/sample_data_model/staging/load_stg_products.sql +0 -0
  82. {sql_glider-0.1.21 → sql_glider-0.1.24}/sqlglider.toml.example +0 -0
  83. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/__init__.py +0 -0
  84. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/catalog/__init__.py +0 -0
  85. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/catalog/base.py +0 -0
  86. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/catalog/databricks.py +0 -0
  87. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/catalog/registry.py +0 -0
  88. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/dissection/__init__.py +0 -0
  89. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/dissection/analyzer.py +0 -0
  90. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/dissection/formatters.py +0 -0
  91. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/dissection/models.py +0 -0
  92. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/global_models.py +0 -0
  93. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/graph/__init__.py +0 -0
  94. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/graph/builder.py +0 -0
  95. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/graph/formatters.py +0 -0
  96. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/graph/merge.py +0 -0
  97. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/graph/models.py +0 -0
  98. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/graph/query.py +0 -0
  99. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/graph/serialization.py +0 -0
  100. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/lineage/__init__.py +0 -0
  101. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/lineage/analyzer.py +0 -0
  102. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/lineage/formatters.py +0 -0
  103. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/schema/__init__.py +0 -0
  104. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/schema/extractor.py +0 -0
  105. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/templating/__init__.py +0 -0
  106. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/templating/base.py +0 -0
  107. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/templating/jinja.py +0 -0
  108. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/templating/registry.py +0 -0
  109. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/templating/variables.py +0 -0
  110. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/utils/__init__.py +0 -0
  111. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/utils/config.py +0 -0
  112. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/utils/file_utils.py +0 -0
  113. {sql_glider-0.1.21 → sql_glider-0.1.24}/src/sqlglider/utils/schema.py +0 -0
  114. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/__init__.py +0 -0
  115. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/multi_file_queries/analytics_pipeline.sql +0 -0
  116. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/multi_file_queries/analytics_pipeline_union_merge.sql +0 -0
  117. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/multi_file_queries/customers.sql +0 -0
  118. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/multi_file_queries/orders.sql +0 -0
  119. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/multi_file_queries/reports.sql +0 -0
  120. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/multi_file_queries/view_based_merge.sql +0 -0
  121. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/original_queries/test_cte.sql +0 -0
  122. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/original_queries/test_cte_query.sql +0 -0
  123. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/original_queries/test_cte_view_star.sql +0 -0
  124. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/original_queries/test_generated_column_query.sql +0 -0
  125. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/original_queries/test_multi.sql +0 -0
  126. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/original_queries/test_multi_query.sql +0 -0
  127. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/original_queries/test_single_query.sql +0 -0
  128. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/original_queries/test_subquery.sql +0 -0
  129. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/original_queries/test_tables.sql +0 -0
  130. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/original_queries/test_view.sql +0 -0
  131. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/original_queries/test_view_window_cte.sql +0 -0
  132. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/fixtures/sample_manifest.csv +0 -0
  133. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/__init__.py +0 -0
  134. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/catalog/__init__.py +0 -0
  135. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/catalog/test_base.py +0 -0
  136. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/catalog/test_databricks.py +0 -0
  137. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/catalog/test_registry.py +0 -0
  138. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/dissection/__init__.py +0 -0
  139. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/dissection/test_analyzer.py +0 -0
  140. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/dissection/test_formatters.py +0 -0
  141. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/dissection/test_models.py +0 -0
  142. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/graph/__init__.py +0 -0
  143. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/graph/test_builder.py +0 -0
  144. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/graph/test_formatters.py +0 -0
  145. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/graph/test_merge.py +0 -0
  146. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/graph/test_models.py +0 -0
  147. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/graph/test_query.py +0 -0
  148. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/graph/test_serialization.py +0 -0
  149. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/lineage/__init__.py +0 -0
  150. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/lineage/test_analyzer.py +0 -0
  151. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/lineage/test_formatters.py +0 -0
  152. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/schema/__init__.py +0 -0
  153. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/schema/test_extractor.py +0 -0
  154. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/templating/__init__.py +0 -0
  155. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/templating/test_base.py +0 -0
  156. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/templating/test_jinja.py +0 -0
  157. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/templating/test_registry.py +0 -0
  158. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/templating/test_variables.py +0 -0
  159. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/test_cli.py +0 -0
  160. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/utils/__init__.py +0 -0
  161. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/utils/test_config.py +0 -0
  162. {sql_glider-0.1.21 → sql_glider-0.1.24}/tests/sqlglider/utils/test_file_utils.py +0 -0
  163. {sql_glider-0.1.21 → sql_glider-0.1.24}/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.24
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
  ![SQL Glider Logo](./docs/docs/static/sqlglider-logo-transparent.png)
@@ -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 'csv' [default: text]
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.21
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
  ![SQL Glider Logo](./docs/docs/static/sqlglider-logo-transparent.png)
@@ -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 'csv' [default: text]
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/) and [DOT (Graphviz)](https://graphviz.org/doc/info/lang.html) formats. These 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.
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,47 @@ 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
+
311
359
  ### Rendering Diagrams
312
360
 
313
361
  **Mermaid:**
@@ -322,6 +370,12 @@ This produces output with the `` ```mermaid `` fence included, so the diagram re
322
370
  - Use `-Tsvg` for scalable vector output
323
371
  - Many IDEs have Graphviz preview extensions
324
372
 
373
+ **Plotly:**
374
+
375
+ - Load the JSON into any Plotly-compatible environment (Python, Dash, Jupyter notebooks)
376
+ - SQL Glider includes a viewer script: `python examples/plotly_viewer.py lineage.json`
377
+ - Export to static images with `fig.write_image("lineage.png")`
378
+
325
379
  ## Building Graphs from Multiple Sources
326
380
 
327
381
  ### Explicit File List
@@ -7,6 +7,8 @@
7
7
  # ============================================================================
8
8
 
9
9
  [project]
10
+ repo_url = "https://github.com/rycowhi/sql-glider/"
11
+ repo_name = "rycowhi/sql-glider"
10
12
 
11
13
  # The site_name is shown in the page header and the browser window title
12
14
  #
@@ -292,15 +294,15 @@ toggle.name = "Switch to dark mode"
292
294
  # - https://zensical.org/docs/setup/logo-and-icons
293
295
  # - https://zensical.org/docs/authoring/icons-emojis/#search
294
296
  # ----------------------------------------------------------------------------
295
- #[project.theme.icon]
297
+ [project.theme.icon]
296
298
  #logo = "lucide/smile"
297
- #repo = "lucide/smile"
299
+ repo = "fontawesome/brands/github"
298
300
 
299
301
  # ----------------------------------------------------------------------------
300
302
  # The "extra" section contains miscellaneous settings.
301
303
  # ----------------------------------------------------------------------------
302
- #[[project.extra.social]]
304
+ [[project.extra.social]]
303
305
  icon = "fontawesome/brands/github"
304
- link = "https://github.com/rycowhi/sql-glider/tree/main/src/sqlglider"
306
+ link = "https://github.com/rycowhi/sql-glider/"
305
307
 
306
308
 
@@ -0,0 +1,109 @@
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(" or: sqlglider graph visualize graph.json -f plotly | python plotly_viewer.py", file=sys.stderr)
37
+ sys.exit(1)
38
+ content = sys.stdin.read()
39
+ if not content.strip():
40
+ print("Error: No input received from stdin", file=sys.stderr)
41
+ print("Note: On Windows, piping may not work reliably.", file=sys.stderr)
42
+ print("Try: sqlglider graph query ... -f plotly -o output.json", file=sys.stderr)
43
+ print("Then: python plotly_viewer.py output.json", file=sys.stderr)
44
+ sys.exit(1)
45
+ else:
46
+ path = Path(source)
47
+ if not path.exists():
48
+ print(f"Error: File not found: {path}", file=sys.stderr)
49
+ sys.exit(1)
50
+ # Try multiple encodings - Windows redirect can create UTF-16 files
51
+ for encoding in ["utf-8", "utf-16", "utf-8-sig"]:
52
+ try:
53
+ content = path.read_text(encoding=encoding)
54
+ break
55
+ except UnicodeDecodeError:
56
+ continue
57
+ else:
58
+ print(f"Error: Could not decode file with UTF-8 or UTF-16 encoding", file=sys.stderr)
59
+ sys.exit(1)
60
+
61
+ try:
62
+ return json.loads(content)
63
+ except json.JSONDecodeError as e:
64
+ print(f"Error: Invalid JSON: {e}", file=sys.stderr)
65
+ if len(content) < 200:
66
+ print(f"Content received: {content!r}", file=sys.stderr)
67
+ else:
68
+ print(f"Content starts with: {content[:200]!r}...", file=sys.stderr)
69
+ sys.exit(1)
70
+
71
+
72
+ def create_app(figure: dict) -> dash.Dash:
73
+ """Create Dash app with the lineage graph."""
74
+ app = dash.Dash(__name__)
75
+
76
+ title = figure.get("layout", {}).get("title", {}).get("text", "Lineage Graph")
77
+
78
+ app.layout = html.Div(
79
+ [
80
+ html.H1(title, style={"textAlign": "center", "fontFamily": "sans-serif"}),
81
+ dcc.Graph(
82
+ id="lineage-graph",
83
+ figure=figure,
84
+ style={"height": "85vh"},
85
+ config={
86
+ "displayModeBar": True,
87
+ "scrollZoom": True,
88
+ "modeBarButtonsToAdd": ["select2d", "lasso2d"],
89
+ },
90
+ ),
91
+ ],
92
+ style={"padding": "20px"},
93
+ )
94
+
95
+ return app
96
+
97
+
98
+ def main():
99
+ source = sys.argv[1] if len(sys.argv) > 1 else None
100
+ figure = load_figure(source)
101
+ app = create_app(figure)
102
+
103
+ print("Starting Dash server at http://127.0.0.1:8050")
104
+ print("Press Ctrl+C to stop")
105
+ app.run(debug=True, host="127.0.0.1", port=8050)
106
+
107
+
108
+ if __name__ == "__main__":
109
+ main()
@@ -35,6 +35,7 @@ dependencies = [
35
35
 
36
36
  [project.optional-dependencies]
37
37
  databricks = ["databricks-sdk>=0.20.0"]
38
+ plotly = ["plotly>=5.0.0"]
38
39
 
39
40
  [project.urls]
40
41
  Homepage = "https://github.com/rycowhi/sql-glider/"
@@ -67,7 +68,9 @@ package = true
67
68
  [dependency-groups]
68
69
  dev = [
69
70
  "basedpyright>=1.36.0",
71
+ "dash>=3.4.0",
70
72
  "databricks-sdk>=0.20.0", # For testing catalog integration
73
+ "plotly>=6.5.2",
71
74
  "pytest>=9.0.1",
72
75
  "pytest-cov>=7.0.0",
73
76
  "pytest-mock>=3.15.1",
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.1.21'
32
- __version_tuple__ = version_tuple = (0, 1, 21)
31
+ __version__ = version = '0.1.24'
32
+ __version_tuple__ = version_tuple = (0, 1, 24)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -1642,7 +1642,7 @@ def graph_query(
1642
1642
  "text",
1643
1643
  "--output-format",
1644
1644
  "-f",
1645
- help="Output format: 'text', 'json', 'csv', 'mermaid', 'mermaid-markdown', or 'dot'",
1645
+ help="Output format: 'text', 'json', 'csv', 'mermaid', 'mermaid-markdown', 'dot', or 'plotly'",
1646
1646
  ),
1647
1647
  ) -> None:
1648
1648
  """
@@ -1661,6 +1661,9 @@ def graph_query(
1661
1661
 
1662
1662
  # CSV output
1663
1663
  sqlglider graph query graph.json --downstream orders.order_id -f csv
1664
+
1665
+ # Plotly JSON output (for Dash/Plotly visualization)
1666
+ sqlglider graph query graph.json --upstream orders.total -f plotly
1664
1667
  """
1665
1668
  from sqlglider.graph.query import GraphQuerier
1666
1669
 
@@ -1678,10 +1681,18 @@ def graph_query(
1678
1681
  )
1679
1682
  raise typer.Exit(1)
1680
1683
 
1681
- if output_format not in ["text", "json", "csv", "mermaid", "mermaid-markdown", "dot"]:
1684
+ if output_format not in [
1685
+ "text",
1686
+ "json",
1687
+ "csv",
1688
+ "mermaid",
1689
+ "mermaid-markdown",
1690
+ "dot",
1691
+ "plotly",
1692
+ ]:
1682
1693
  err_console.print(
1683
1694
  f"[red]Error:[/red] Invalid output format '{output_format}'. "
1684
- "Use 'text', 'json', 'csv', 'mermaid', 'mermaid-markdown', or 'dot'."
1695
+ "Use 'text', 'json', 'csv', 'mermaid', 'mermaid-markdown', 'dot', or 'plotly'."
1685
1696
  )
1686
1697
  raise typer.Exit(1)
1687
1698
 
@@ -1713,6 +1724,14 @@ def graph_query(
1713
1724
  from sqlglider.graph.diagram_formatters import DotFormatter
1714
1725
 
1715
1726
  print(DotFormatter.format_query_result(result))
1727
+ elif output_format == "plotly":
1728
+ from sqlglider.graph.diagram_formatters import PlotlyFormatter
1729
+
1730
+ print(PlotlyFormatter.format_query_result(result))
1731
+
1732
+ except ImportError as e:
1733
+ err_console.print(f"[red]Error:[/red] {e}")
1734
+ raise typer.Exit(1)
1716
1735
 
1717
1736
  except FileNotFoundError as e:
1718
1737
  err_console.print(f"[red]Error:[/red] {e}")
@@ -1818,7 +1837,7 @@ def graph_visualize(
1818
1837
  "mermaid",
1819
1838
  "--output-format",
1820
1839
  "-f",
1821
- help="Diagram format: 'mermaid', 'mermaid-markdown', or 'dot'",
1840
+ help="Diagram format: 'mermaid', 'mermaid-markdown', 'dot', or 'plotly'",
1822
1841
  ),
1823
1842
  output_file: Optional[Path] = typer.Option(
1824
1843
  None,
@@ -1830,8 +1849,8 @@ def graph_visualize(
1830
1849
  """
1831
1850
  Visualize the entire lineage graph as a diagram.
1832
1851
 
1833
- Generates Mermaid or DOT (Graphviz) diagrams showing all nodes and edges
1834
- in the graph for visualization tools.
1852
+ Generates Mermaid, DOT (Graphviz), or Plotly JSON diagrams showing all
1853
+ nodes and edges in the graph for visualization tools.
1835
1854
 
1836
1855
  Examples:
1837
1856
 
@@ -1846,18 +1865,16 @@ def graph_visualize(
1846
1865
 
1847
1866
  # Render DOT to PNG with Graphviz
1848
1867
  sqlglider graph visualize graph.json -f dot -o lineage.dot
1868
+
1869
+ # Generate Plotly JSON for Dash/Plotly apps
1870
+ sqlglider graph visualize graph.json -f plotly -o lineage.json
1849
1871
  """
1850
- from sqlglider.graph.diagram_formatters import (
1851
- DotFormatter,
1852
- MermaidFormatter,
1853
- MermaidMarkdownFormatter,
1854
- )
1855
1872
  from sqlglider.graph.serialization import load_graph
1856
1873
 
1857
- if output_format not in ["mermaid", "mermaid-markdown", "dot"]:
1874
+ if output_format not in ["mermaid", "mermaid-markdown", "dot", "plotly"]:
1858
1875
  err_console.print(
1859
1876
  f"[red]Error:[/red] Invalid output format '{output_format}'. "
1860
- "Use 'mermaid', 'mermaid-markdown', or 'dot'."
1877
+ "Use 'mermaid', 'mermaid-markdown', 'dot', or 'plotly'."
1861
1878
  )
1862
1879
  raise typer.Exit(1)
1863
1880
 
@@ -1865,20 +1882,32 @@ def graph_visualize(
1865
1882
  graph = load_graph(graph_file)
1866
1883
 
1867
1884
  if output_format == "mermaid":
1885
+ from sqlglider.graph.diagram_formatters import MermaidFormatter
1886
+
1868
1887
  diagram = MermaidFormatter.format_full_graph(graph)
1869
1888
  elif output_format == "mermaid-markdown":
1889
+ from sqlglider.graph.diagram_formatters import MermaidMarkdownFormatter
1890
+
1870
1891
  diagram = MermaidMarkdownFormatter.format_full_graph(graph)
1871
- else:
1892
+ elif output_format == "dot":
1893
+ from sqlglider.graph.diagram_formatters import DotFormatter
1894
+
1872
1895
  diagram = DotFormatter.format_full_graph(graph)
1896
+ else: # plotly
1897
+ from sqlglider.graph.diagram_formatters import PlotlyFormatter
1898
+
1899
+ diagram = PlotlyFormatter.format_full_graph(graph)
1873
1900
 
1874
1901
  if output_file:
1875
1902
  output_file.write_text(diagram, encoding="utf-8")
1876
- console.print(
1877
- f"[green]Success:[/green] Diagram written to {output_file}"
1878
- )
1903
+ console.print(f"[green]Success:[/green] Diagram written to {output_file}")
1879
1904
  else:
1880
1905
  print(diagram)
1881
1906
 
1907
+ except ImportError as e:
1908
+ err_console.print(f"[red]Error:[/red] {e}")
1909
+ raise typer.Exit(1)
1910
+
1882
1911
  except FileNotFoundError as e:
1883
1912
  err_console.print(f"[red]Error:[/red] {e}")
1884
1913
  raise typer.Exit(1)