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.
- {sql_glider-0.1.25 → sql_glider-0.1.26}/PKG-INFO +1 -1
- {sql_glider-0.1.25 → sql_glider-0.1.26}/docs/docs/graph-lineage.md +10 -8
- sql_glider-0.1.26/mm.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/_version.py +2 -2
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/cli.py +6 -2
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/graph/diagram_formatters.py +35 -9
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/graph/test_diagram_formatters.py +49 -7
- {sql_glider-0.1.25 → sql_glider-0.1.26}/.github/workflows/ci.yml +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/.github/workflows/docs.yml +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/.github/workflows/publish.yml +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/.gitignore +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/.python-version +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/ARCHITECTURE.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/CLAUDE.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/LICENSE +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/README.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/docs/.github/workflows/docs.yml +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/docs/docs/catalogs.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/docs/docs/index.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/docs/docs/static/plotly-dash-example.png +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/docs/docs/static/sqlglider-logo-transparent.png +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/docs/docs/templating.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/docs/zensical.toml +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/examples/plotly_viewer.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/graph.json +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/lineage.json +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-05-column-level-lineage.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-05-reverse-lineage.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-06-config-file-support.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-06-graph-lineage.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-06-unify-single-multi-query.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-07-sample-data-model.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-07-sql-templating.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-08-tables-command.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-09-graph-query-paths.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-13-dissect-command.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2025-12-14-tables-pull-command.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2026-01-25-fix-union-lineage-chain.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2026-01-26-file-scoped-schema-context.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2026-01-28-sparksql-table-extraction.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2026-01-29-no-star-flag.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2026-01-29-resolve-schema.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2026-01-29-schema-pruning-optimization.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2026-01-29-tables-scrape-command.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/plans/2026-02-02-diagram-output-formats.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/pyproject.toml +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/README.md +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/business/expire_dim_customer.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/business/load_fact_orders.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/business/load_fact_payments.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/business/merge_dim_customer.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/business/merge_dim_product.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/business/update_dim_customer_metrics.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/complex/conditional_merge.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/complex/cte_insert.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/complex/multi_table_transform.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/dim_customer.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/dim_product.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/fact_orders.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/fact_payments.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/raw_addresses.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/raw_customers.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/raw_order_items.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/raw_orders.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/raw_payments.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/raw_products.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/stg_customers.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/stg_orders.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/stg_payments.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/ddl/stg_products.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/incremental/incr_fact_orders.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/incremental/incr_fact_payments.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/incremental/incr_pres_sales_summary.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/maintenance/delete_expired_customers.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/maintenance/update_product_status.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/presentation/load_pres_customer_360.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/presentation/load_pres_customer_cohort.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/presentation/load_pres_product_performance.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/presentation/load_pres_sales_summary.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/staging/load_stg_customers.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/staging/load_stg_orders.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/staging/load_stg_payments.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/staging/load_stg_products.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/sqlglider.toml.example +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/__init__.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/catalog/__init__.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/catalog/base.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/catalog/databricks.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/catalog/registry.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/dissection/__init__.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/dissection/analyzer.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/dissection/formatters.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/dissection/models.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/global_models.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/graph/__init__.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/graph/builder.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/graph/formatters.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/graph/merge.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/graph/models.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/graph/query.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/graph/serialization.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/lineage/__init__.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/lineage/analyzer.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/lineage/formatters.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/schema/__init__.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/schema/extractor.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/templating/__init__.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/templating/base.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/templating/jinja.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/templating/registry.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/templating/variables.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/utils/__init__.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/utils/config.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/utils/file_utils.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/src/sqlglider/utils/schema.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/__init__.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/multi_file_queries/analytics_pipeline.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/multi_file_queries/analytics_pipeline_union_merge.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/multi_file_queries/customers.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/multi_file_queries/orders.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/multi_file_queries/reports.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/multi_file_queries/view_based_merge.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_cte.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_cte_query.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_cte_view_star.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_generated_column_query.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_multi.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_multi_query.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_single_query.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_subquery.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_tables.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_view.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_view_window_cte.sql +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/sample_manifest.csv +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/__init__.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/catalog/__init__.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/catalog/test_base.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/catalog/test_databricks.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/catalog/test_registry.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/dissection/__init__.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/dissection/test_analyzer.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/dissection/test_formatters.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/dissection/test_models.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/graph/__init__.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/graph/test_builder.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/graph/test_formatters.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/graph/test_merge.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/graph/test_models.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/graph/test_query.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/graph/test_serialization.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/lineage/__init__.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/lineage/test_analyzer.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/lineage/test_formatters.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/schema/__init__.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/schema/test_extractor.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/templating/__init__.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/templating/test_base.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/templating/test_jinja.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/templating/test_registry.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/templating/test_variables.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/test_cli.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/utils/__init__.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/utils/test_config.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/utils/test_file_utils.py +0 -0
- {sql_glider-0.1.25 → sql_glider-0.1.26}/tests/sqlglider/utils/test_schema.py +0 -0
- {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.
|
|
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
|
|
281
|
-
raw_orders_tax
|
|
282
|
-
staging_orders_subtotal
|
|
283
|
-
staging_orders_tax_amount
|
|
284
|
-
raw_exchange_rates_rate
|
|
285
|
-
mart_orders_total_usd
|
|
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
|
|
sql_glider-0.1.26/mm.md
ADDED
|
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.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 1,
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
145
|
-
|
|
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(
|
|
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
|
-
|
|
239
|
-
assert "
|
|
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
|
-
|
|
244
|
-
assert "a_col
|
|
245
|
-
assert "
|
|
246
|
-
assert "
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/business/update_dim_customer_metrics.sql
RENAMED
|
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
|
|
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
|
{sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/incremental/incr_fact_payments.sql
RENAMED
|
File without changes
|
{sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/incremental/incr_pres_sales_summary.sql
RENAMED
|
File without changes
|
{sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/maintenance/delete_expired_customers.sql
RENAMED
|
File without changes
|
{sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/maintenance/update_product_status.sql
RENAMED
|
File without changes
|
{sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/presentation/load_pres_customer_360.sql
RENAMED
|
File without changes
|
{sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/presentation/load_pres_customer_cohort.sql
RENAMED
|
File without changes
|
|
File without changes
|
{sql_glider-0.1.25 → sql_glider-0.1.26}/sample_data_model/presentation/load_pres_sales_summary.sql
RENAMED
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/multi_file_queries/analytics_pipeline.sql
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/multi_file_queries/view_based_merge.sql
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_cte_view_star.sql
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_multi_query.sql
RENAMED
|
File without changes
|
{sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_single_query.sql
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sql_glider-0.1.25 → sql_glider-0.1.26}/tests/fixtures/original_queries/test_view_window_cte.sql
RENAMED
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|