sql-glider 0.1.25__tar.gz → 0.1.26__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 (166) hide show
  1. {sql_glider-0.1.25 → sql_glider-0.1.26}/PKG-INFO +1 -1
  2. {sql_glider-0.1.25 → sql_glider-0.1.26}/docs/docs/graph-lineage.md +10 -8
  3. sql_glider-0.1.26/mm.md +0 -0
  4. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/_version.py +2 -2
  5. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/cli.py +6 -2
  6. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/graph/diagram_formatters.py +35 -9
  7. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/graph/test_diagram_formatters.py +49 -7
  8. {sql_glider-0.1.25 → sql_glider-0.1.26}/.github/workflows/ci.yml +0 -0
  9. {sql_glider-0.1.25 → sql_glider-0.1.26}/.github/workflows/docs.yml +0 -0
  10. {sql_glider-0.1.25 → sql_glider-0.1.26}/.github/workflows/publish.yml +0 -0
  11. {sql_glider-0.1.25 → sql_glider-0.1.26}/.gitignore +0 -0
  12. {sql_glider-0.1.25 → sql_glider-0.1.26}/.python-version +0 -0
  13. {sql_glider-0.1.25 → sql_glider-0.1.26}/ARCHITECTURE.md +0 -0
  14. {sql_glider-0.1.25 → sql_glider-0.1.26}/CLAUDE.md +0 -0
  15. {sql_glider-0.1.25 → sql_glider-0.1.26}/LICENSE +0 -0
  16. {sql_glider-0.1.25 → sql_glider-0.1.26}/README.md +0 -0
  17. {sql_glider-0.1.25 → sql_glider-0.1.26}/docs/.github/workflows/docs.yml +0 -0
  18. {sql_glider-0.1.25 → sql_glider-0.1.26}/docs/docs/catalogs.md +0 -0
  19. {sql_glider-0.1.25 → sql_glider-0.1.26}/docs/docs/index.md +0 -0
  20. {sql_glider-0.1.25 → sql_glider-0.1.26}/docs/docs/static/plotly-dash-example.png +0 -0
  21. {sql_glider-0.1.25 → sql_glider-0.1.26}/docs/docs/static/sqlglider-logo-transparent.png +0 -0
  22. {sql_glider-0.1.25 → sql_glider-0.1.26}/docs/docs/templating.md +0 -0
  23. {sql_glider-0.1.25 → sql_glider-0.1.26}/docs/zensical.toml +0 -0
  24. {sql_glider-0.1.25 → sql_glider-0.1.26}/examples/plotly_viewer.py +0 -0
  25. {sql_glider-0.1.25 → sql_glider-0.1.26}/graph.json +0 -0
  26. {sql_glider-0.1.25 → sql_glider-0.1.26}/lineage.json +0 -0
  27. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-05-column-level-lineage.md +0 -0
  28. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-05-reverse-lineage.md +0 -0
  29. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-06-config-file-support.md +0 -0
  30. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-06-graph-lineage.md +0 -0
  31. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-06-unify-single-multi-query.md +0 -0
  32. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-07-sample-data-model.md +0 -0
  33. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-07-sql-templating.md +0 -0
  34. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-08-tables-command.md +0 -0
  35. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-09-graph-query-paths.md +0 -0
  36. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-13-dissect-command.md +0 -0
  37. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-14-tables-pull-command.md +0 -0
  38. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2026-01-25-fix-union-lineage-chain.md +0 -0
  39. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2026-01-26-file-scoped-schema-context.md +0 -0
  40. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2026-01-28-sparksql-table-extraction.md +0 -0
  41. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2026-01-29-no-star-flag.md +0 -0
  42. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2026-01-29-resolve-schema.md +0 -0
  43. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2026-01-29-schema-pruning-optimization.md +0 -0
  44. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2026-01-29-tables-scrape-command.md +0 -0
  45. {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2026-02-02-diagram-output-formats.md +0 -0
  46. {sql_glider-0.1.25 → sql_glider-0.1.26}/pyproject.toml +0 -0
  47. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/README.md +0 -0
  48. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/business/expire_dim_customer.sql +0 -0
  49. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/business/load_fact_orders.sql +0 -0
  50. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/business/load_fact_payments.sql +0 -0
  51. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/business/merge_dim_customer.sql +0 -0
  52. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/business/merge_dim_product.sql +0 -0
  53. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/business/update_dim_customer_metrics.sql +0 -0
  54. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/complex/conditional_merge.sql +0 -0
  55. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/complex/cte_insert.sql +0 -0
  56. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/complex/multi_table_transform.sql +0 -0
  57. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/dim_customer.sql +0 -0
  58. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/dim_product.sql +0 -0
  59. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/fact_orders.sql +0 -0
  60. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/fact_payments.sql +0 -0
  61. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/raw_addresses.sql +0 -0
  62. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/raw_customers.sql +0 -0
  63. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/raw_order_items.sql +0 -0
  64. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/raw_orders.sql +0 -0
  65. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/raw_payments.sql +0 -0
  66. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/raw_products.sql +0 -0
  67. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/stg_customers.sql +0 -0
  68. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/stg_orders.sql +0 -0
  69. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/stg_payments.sql +0 -0
  70. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/stg_products.sql +0 -0
  71. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/incremental/incr_fact_orders.sql +0 -0
  72. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/incremental/incr_fact_payments.sql +0 -0
  73. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/incremental/incr_pres_sales_summary.sql +0 -0
  74. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/maintenance/delete_expired_customers.sql +0 -0
  75. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/maintenance/update_product_status.sql +0 -0
  76. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/presentation/load_pres_customer_360.sql +0 -0
  77. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/presentation/load_pres_customer_cohort.sql +0 -0
  78. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/presentation/load_pres_product_performance.sql +0 -0
  79. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/presentation/load_pres_sales_summary.sql +0 -0
  80. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/staging/load_stg_customers.sql +0 -0
  81. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/staging/load_stg_orders.sql +0 -0
  82. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/staging/load_stg_payments.sql +0 -0
  83. {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/staging/load_stg_products.sql +0 -0
  84. {sql_glider-0.1.25 → sql_glider-0.1.26}/sqlglider.toml.example +0 -0
  85. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/__init__.py +0 -0
  86. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/catalog/__init__.py +0 -0
  87. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/catalog/base.py +0 -0
  88. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/catalog/databricks.py +0 -0
  89. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/catalog/registry.py +0 -0
  90. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/dissection/__init__.py +0 -0
  91. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/dissection/analyzer.py +0 -0
  92. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/dissection/formatters.py +0 -0
  93. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/dissection/models.py +0 -0
  94. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/global_models.py +0 -0
  95. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/graph/__init__.py +0 -0
  96. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/graph/builder.py +0 -0
  97. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/graph/formatters.py +0 -0
  98. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/graph/merge.py +0 -0
  99. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/graph/models.py +0 -0
  100. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/graph/query.py +0 -0
  101. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/graph/serialization.py +0 -0
  102. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/lineage/__init__.py +0 -0
  103. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/lineage/analyzer.py +0 -0
  104. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/lineage/formatters.py +0 -0
  105. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/schema/__init__.py +0 -0
  106. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/schema/extractor.py +0 -0
  107. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/templating/__init__.py +0 -0
  108. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/templating/base.py +0 -0
  109. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/templating/jinja.py +0 -0
  110. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/templating/registry.py +0 -0
  111. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/templating/variables.py +0 -0
  112. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/utils/__init__.py +0 -0
  113. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/utils/config.py +0 -0
  114. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/utils/file_utils.py +0 -0
  115. {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/utils/schema.py +0 -0
  116. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/__init__.py +0 -0
  117. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/multi_file_queries/analytics_pipeline.sql +0 -0
  118. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/multi_file_queries/analytics_pipeline_union_merge.sql +0 -0
  119. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/multi_file_queries/customers.sql +0 -0
  120. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/multi_file_queries/orders.sql +0 -0
  121. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/multi_file_queries/reports.sql +0 -0
  122. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/multi_file_queries/view_based_merge.sql +0 -0
  123. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_cte.sql +0 -0
  124. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_cte_query.sql +0 -0
  125. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_cte_view_star.sql +0 -0
  126. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_generated_column_query.sql +0 -0
  127. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_multi.sql +0 -0
  128. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_multi_query.sql +0 -0
  129. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_single_query.sql +0 -0
  130. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_subquery.sql +0 -0
  131. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_tables.sql +0 -0
  132. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_view.sql +0 -0
  133. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_view_window_cte.sql +0 -0
  134. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/sample_manifest.csv +0 -0
  135. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/__init__.py +0 -0
  136. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/catalog/__init__.py +0 -0
  137. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/catalog/test_base.py +0 -0
  138. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/catalog/test_databricks.py +0 -0
  139. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/catalog/test_registry.py +0 -0
  140. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/dissection/__init__.py +0 -0
  141. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/dissection/test_analyzer.py +0 -0
  142. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/dissection/test_formatters.py +0 -0
  143. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/dissection/test_models.py +0 -0
  144. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/graph/__init__.py +0 -0
  145. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/graph/test_builder.py +0 -0
  146. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/graph/test_formatters.py +0 -0
  147. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/graph/test_merge.py +0 -0
  148. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/graph/test_models.py +0 -0
  149. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/graph/test_query.py +0 -0
  150. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/graph/test_serialization.py +0 -0
  151. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/lineage/__init__.py +0 -0
  152. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/lineage/test_analyzer.py +0 -0
  153. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/lineage/test_formatters.py +0 -0
  154. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/schema/__init__.py +0 -0
  155. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/schema/test_extractor.py +0 -0
  156. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/templating/__init__.py +0 -0
  157. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/templating/test_base.py +0 -0
  158. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/templating/test_jinja.py +0 -0
  159. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/templating/test_registry.py +0 -0
  160. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/templating/test_variables.py +0 -0
  161. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/test_cli.py +0 -0
  162. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/utils/__init__.py +0 -0
  163. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/utils/test_config.py +0 -0
  164. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/utils/test_file_utils.py +0 -0
  165. {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/utils/test_schema.py +0 -0
  166. {sql_glider-0.1.25 → sql_glider-0.1.26}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sql-glider
3
- Version: 0.1.25
3
+ Version: 0.1.26
4
4
  Summary: SQL Utility Toolkit for better understanding, use, and governance of your queries in a native environment.
5
5
  Project-URL: Homepage, https://github.com/rycowhi/sql-glider/
6
6
  Project-URL: Repository, https://github.com/rycowhi/sql-glider/
@@ -258,7 +258,7 @@ sqlglider graph query graph.json --downstream orders.order_total -f dot
258
258
  sqlglider graph query graph.json --upstream total_spent -f plotly
259
259
  ```
260
260
 
261
- Query diagrams include color-coded nodes and a legend:
261
+ Query diagrams include color-coded nodes, edge labels showing the source SQL file, and a legend:
262
262
 
263
263
  | Color | Meaning |
264
264
  |--------|---------|
@@ -266,6 +266,8 @@ Query diagrams include color-coded nodes and a legend:
266
266
  | Teal | Root node (no upstream dependencies) |
267
267
  | Violet | Leaf node (no downstream consumers) |
268
268
 
269
+ Each edge in the diagram is labeled with the SQL filename that defines that relationship, making it easy to trace data flow back to the source code.
270
+
269
271
  **Example:** Imagine a pipeline where a `revenue` report column draws from multiple sources through several transformation layers. Querying `--upstream revenue` would produce a diagram like this:
270
272
 
271
273
  ```mermaid
@@ -277,12 +279,12 @@ flowchart TD
277
279
  staging_orders_tax_amount["staging_orders.tax_amount"]
278
280
  mart_orders_total_usd["mart_orders.total_usd"]
279
281
  revenue["revenue"]
280
- raw_orders_amount --> staging_orders_subtotal
281
- raw_orders_tax --> staging_orders_tax_amount
282
- staging_orders_subtotal --> mart_orders_total_usd
283
- staging_orders_tax_amount --> mart_orders_total_usd
284
- raw_exchange_rates_rate --> mart_orders_total_usd
285
- mart_orders_total_usd --> revenue
282
+ raw_orders_amount -->|staging_orders.sql| staging_orders_subtotal
283
+ raw_orders_tax -->|staging_orders.sql| staging_orders_tax_amount
284
+ staging_orders_subtotal -->|mart_orders.sql| mart_orders_total_usd
285
+ staging_orders_tax_amount -->|mart_orders.sql| mart_orders_total_usd
286
+ raw_exchange_rates_rate -->|mart_orders.sql| mart_orders_total_usd
287
+ mart_orders_total_usd -->|reports.sql| revenue
286
288
 
287
289
  style revenue fill:#e6a843,stroke:#b8860b,stroke-width:3px
288
290
  style raw_orders_amount fill:#4ecdc4,stroke:#2b9e96
@@ -299,7 +301,7 @@ flowchart TD
299
301
  style legend_leaf fill:#c084fc,stroke:#7c3aed
300
302
  ```
301
303
 
302
- The amber node is the column you queried (`revenue`), teal nodes are ultimate root sources with no further upstream dependencies (`raw_orders.amount`, `raw_orders.tax`, `raw_exchange_rates.rate`), and intermediate nodes (`staging_orders.*`, `mart_orders.*`) appear in the default style. The legend is included automatically.
304
+ The amber node is the column you queried (`revenue`), teal nodes are ultimate root sources with no further upstream dependencies (`raw_orders.amount`, `raw_orders.tax`, `raw_exchange_rates.rate`), and intermediate nodes (`staging_orders.*`, `mart_orders.*`) appear in the default style. Each edge is labeled with the SQL file that defines that relationship. The legend is included automatically.
303
305
 
304
306
  ### Mermaid Markdown Format
305
307
 
Binary file
@@ -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.25'
32
- __version_tuple__ = version_tuple = (0, 1, 25)
31
+ __version__ = version = '0.1.26'
32
+ __version_tuple__ = version_tuple = (0, 1, 26)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -1715,11 +1715,15 @@ def graph_query(
1715
1715
  elif output_format == "mermaid":
1716
1716
  from sqlglider.graph.diagram_formatters import MermaidFormatter
1717
1717
 
1718
- print(MermaidFormatter.format_query_result(result))
1718
+ print(MermaidFormatter.format_query_result(result, graph=querier.graph))
1719
1719
  elif output_format == "mermaid-markdown":
1720
1720
  from sqlglider.graph.diagram_formatters import MermaidMarkdownFormatter
1721
1721
 
1722
- print(MermaidMarkdownFormatter.format_query_result(result))
1722
+ print(
1723
+ MermaidMarkdownFormatter.format_query_result(
1724
+ result, graph=querier.graph
1725
+ )
1726
+ )
1723
1727
  elif output_format == "dot":
1724
1728
  from sqlglider.graph.diagram_formatters import DotFormatter
1725
1729
 
@@ -102,16 +102,26 @@ class MermaidFormatter:
102
102
  node_id = _sanitize_mermaid_id(node.identifier)
103
103
  lines.append(f' {node_id}["{node.identifier}"]')
104
104
 
105
- # Add edges
105
+ # Add edges with file path labels
106
106
  for edge in graph.edges:
107
107
  src = _sanitize_mermaid_id(edge.source_node)
108
108
  tgt = _sanitize_mermaid_id(edge.target_node)
109
- lines.append(f" {src} --> {tgt}")
109
+ # Extract filename from path
110
+ file_name = (
111
+ edge.file_path.split("/")[-1].split("\\")[-1] if edge.file_path else ""
112
+ )
113
+ if file_name:
114
+ lines.append(f" {src} -->|{file_name}| {tgt}")
115
+ else:
116
+ lines.append(f" {src} --> {tgt}")
110
117
 
111
118
  return "\n".join(lines)
112
119
 
113
120
  @staticmethod
114
- def format_query_result(result: LineageQueryResult) -> str:
121
+ def format_query_result(
122
+ result: LineageQueryResult,
123
+ graph: Optional[LineageGraph] = None,
124
+ ) -> str:
115
125
  """Format query result as a Mermaid flowchart with styling.
116
126
 
117
127
  The queried column is highlighted in amber, root nodes in teal,
@@ -119,6 +129,7 @@ class MermaidFormatter:
119
129
 
120
130
  Args:
121
131
  result: LineageQueryResult from upstream/downstream query
132
+ graph: Optional LineageGraph for edge file path labels
122
133
 
123
134
  Returns:
124
135
  Mermaid diagram string with style directives and legend
@@ -134,16 +145,27 @@ class MermaidFormatter:
134
145
  all_nodes = _collect_query_nodes(result)
135
146
  edges = _collect_query_edges(result)
136
147
 
148
+ # Build edge file path lookup if graph is provided
149
+ edge_file_paths: dict[tuple[str, str], str] = {}
150
+ if graph:
151
+ for e in graph.edges:
152
+ edge_file_paths[(e.source_node, e.target_node)] = e.file_path
153
+
137
154
  # Declare nodes
138
155
  for identifier in sorted(all_nodes):
139
156
  node_id = _sanitize_mermaid_id(identifier)
140
157
  lines.append(f' {node_id}["{identifier}"]')
141
158
 
142
- # Add edges
159
+ # Add edges with optional file path labels
143
160
  for src, tgt in sorted(edges):
144
- lines.append(
145
- f" {_sanitize_mermaid_id(src)} --> {_sanitize_mermaid_id(tgt)}"
146
- )
161
+ src_id = _sanitize_mermaid_id(src)
162
+ tgt_id = _sanitize_mermaid_id(tgt)
163
+ file_path = edge_file_paths.get((src, tgt), "")
164
+ file_name = file_path.split("/")[-1].split("\\")[-1] if file_path else ""
165
+ if file_name:
166
+ lines.append(f" {src_id} -->|{file_name}| {tgt_id}")
167
+ else:
168
+ lines.append(f" {src_id} --> {tgt_id}")
147
169
 
148
170
  # Style directives
149
171
  queried_id = _sanitize_mermaid_id(result.query_column)
@@ -200,16 +222,20 @@ class MermaidMarkdownFormatter:
200
222
  return f"```mermaid\n{mermaid}\n```"
201
223
 
202
224
  @staticmethod
203
- def format_query_result(result: LineageQueryResult) -> str:
225
+ def format_query_result(
226
+ result: LineageQueryResult,
227
+ graph: Optional[LineageGraph] = None,
228
+ ) -> str:
204
229
  """Format query result as a Mermaid diagram in a markdown code block.
205
230
 
206
231
  Args:
207
232
  result: LineageQueryResult from upstream/downstream query
233
+ graph: Optional LineageGraph for edge file path labels
208
234
 
209
235
  Returns:
210
236
  Markdown string with fenced Mermaid diagram
211
237
  """
212
- mermaid = MermaidFormatter.format_query_result(result)
238
+ mermaid = MermaidFormatter.format_query_result(result, graph=graph)
213
239
  return f"```mermaid\n{mermaid}\n```"
214
240
 
215
241
 
@@ -235,15 +235,17 @@ class TestMermaidFormatterFullGraph:
235
235
 
236
236
  def test_linear_graph_has_edges(self, linear_graph):
237
237
  result = MermaidFormatter.format_full_graph(linear_graph)
238
- assert "a_col --> b_col" in result
239
- assert "b_col --> c_col" in result
238
+ # Edges now include file path labels
239
+ assert "a_col -->|q.sql| b_col" in result
240
+ assert "b_col -->|q.sql| c_col" in result
240
241
 
241
242
  def test_diamond_graph_edges(self, diamond_graph):
242
243
  result = MermaidFormatter.format_full_graph(diamond_graph)
243
- assert "a_col --> b_col" in result
244
- assert "a_col --> c_col" in result
245
- assert "b_col --> d_col" in result
246
- assert "c_col --> d_col" in result
244
+ # Edges now include file path labels
245
+ assert "a_col -->|q.sql| b_col" in result
246
+ assert "a_col -->|q.sql| c_col" in result
247
+ assert "b_col -->|q.sql| d_col" in result
248
+ assert "c_col -->|q.sql| d_col" in result
247
249
 
248
250
  def test_starts_with_flowchart(self, linear_graph):
249
251
  result = MermaidFormatter.format_full_graph(linear_graph)
@@ -285,6 +287,45 @@ class TestMermaidFormatterQueryResult:
285
287
  result = MermaidFormatter.format_query_result(empty_query_result)
286
288
  assert "Legend" not in result
287
289
 
290
+ def test_with_graph_has_edge_labels(self, upstream_query_result):
291
+ """Test that passing a graph adds edge file path labels."""
292
+ # Create a graph that matches the query result edges
293
+ matching_graph = LineageGraph(
294
+ nodes=[
295
+ GraphNode.from_identifier("source.col", "/path/lineage.sql", 0),
296
+ GraphNode.from_identifier("mid.col", "/path/lineage.sql", 0),
297
+ GraphNode.from_identifier("target.col", "/path/lineage.sql", 0),
298
+ ],
299
+ edges=[
300
+ GraphEdge(
301
+ source_node="source.col",
302
+ target_node="mid.col",
303
+ file_path="/path/lineage.sql",
304
+ query_index=0,
305
+ ),
306
+ GraphEdge(
307
+ source_node="mid.col",
308
+ target_node="target.col",
309
+ file_path="/path/lineage.sql",
310
+ query_index=0,
311
+ ),
312
+ ],
313
+ )
314
+
315
+ result = MermaidFormatter.format_query_result(
316
+ upstream_query_result, graph=matching_graph
317
+ )
318
+ # Edges should have file path labels
319
+ assert "-->|lineage.sql|" in result
320
+
321
+ def test_without_graph_no_edge_labels(self, upstream_query_result):
322
+ """Test that without graph parameter, edges have no labels."""
323
+ result = MermaidFormatter.format_query_result(upstream_query_result)
324
+ # Edges should not have labels (no |...|)
325
+ assert "source_col --> mid_col" in result
326
+ assert "mid_col --> target_col" in result
327
+ assert "-->|" not in result
328
+
288
329
 
289
330
  # --- DotFormatter tests ---
290
331
 
@@ -382,7 +423,8 @@ class TestMermaidMarkdownFormatterFullGraph:
382
423
  def test_contains_mermaid_content(self, linear_graph):
383
424
  result = MermaidMarkdownFormatter.format_full_graph(linear_graph)
384
425
  assert "flowchart TD" in result
385
- assert "a_col --> b_col" in result
426
+ # Edges now include file path labels
427
+ assert "a_col -->|q.sql| b_col" in result
386
428
 
387
429
  def test_empty_graph(self, empty_graph):
388
430
  result = MermaidMarkdownFormatter.format_full_graph(empty_graph)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes