sql-glider 0.1.20__tar.gz → 0.1.23__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sql_glider-0.1.23/.github/workflows/docs.yml +54 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/.gitignore +2 -1
- {sql_glider-0.1.20 → sql_glider-0.1.23}/ARCHITECTURE.md +10 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/CLAUDE.md +17 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/PKG-INFO +41 -1
- {sql_glider-0.1.20 → sql_glider-0.1.23}/README.md +40 -0
- sql_glider-0.1.23/docs/.github/workflows/docs.yml +29 -0
- sql_glider-0.1.23/docs/docs/catalogs.md +190 -0
- sql_glider-0.1.23/docs/docs/graph-lineage.md +399 -0
- sql_glider-0.1.23/docs/docs/index.md +51 -0
- sql_glider-0.1.23/docs/docs/static/sqlglider-logo-transparent.png +0 -0
- sql_glider-0.1.23/docs/docs/templating.md +235 -0
- sql_glider-0.1.23/docs/zensical.toml +308 -0
- sql_glider-0.1.23/plans/2026-02-02-diagram-output-formats.md +62 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/pyproject.toml +4 -1
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/_version.py +2 -2
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/cli.py +106 -4
- sql_glider-0.1.23/src/sqlglider/graph/diagram_formatters.py +330 -0
- sql_glider-0.1.23/tests/sqlglider/graph/test_diagram_formatters.py +414 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/uv.lock +63 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/.github/workflows/ci.yml +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/.github/workflows/publish.yml +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/.python-version +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/LICENSE +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2025-12-05-column-level-lineage.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2025-12-05-reverse-lineage.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2025-12-06-config-file-support.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2025-12-06-graph-lineage.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2025-12-06-unify-single-multi-query.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2025-12-07-sample-data-model.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2025-12-07-sql-templating.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2025-12-08-tables-command.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2025-12-09-graph-query-paths.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2025-12-13-dissect-command.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2025-12-14-tables-pull-command.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2026-01-25-fix-union-lineage-chain.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2026-01-26-file-scoped-schema-context.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2026-01-28-sparksql-table-extraction.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2026-01-29-no-star-flag.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2026-01-29-resolve-schema.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2026-01-29-schema-pruning-optimization.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/plans/2026-01-29-tables-scrape-command.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/README.md +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/business/expire_dim_customer.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/business/load_fact_orders.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/business/load_fact_payments.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/business/merge_dim_customer.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/business/merge_dim_product.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/business/update_dim_customer_metrics.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/complex/conditional_merge.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/complex/cte_insert.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/complex/multi_table_transform.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/ddl/dim_customer.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/ddl/dim_product.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/ddl/fact_orders.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/ddl/fact_payments.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/ddl/raw_addresses.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/ddl/raw_customers.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/ddl/raw_order_items.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/ddl/raw_orders.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/ddl/raw_payments.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/ddl/raw_products.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/ddl/stg_customers.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/ddl/stg_orders.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/ddl/stg_payments.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/ddl/stg_products.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/incremental/incr_fact_orders.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/incremental/incr_fact_payments.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/incremental/incr_pres_sales_summary.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/maintenance/delete_expired_customers.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/maintenance/update_product_status.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/presentation/load_pres_customer_360.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/presentation/load_pres_customer_cohort.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/presentation/load_pres_product_performance.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/presentation/load_pres_sales_summary.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/staging/load_stg_customers.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/staging/load_stg_orders.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/staging/load_stg_payments.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sample_data_model/staging/load_stg_products.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/sqlglider.toml.example +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/__init__.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/catalog/__init__.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/catalog/base.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/catalog/databricks.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/catalog/registry.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/dissection/__init__.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/dissection/analyzer.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/dissection/formatters.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/dissection/models.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/global_models.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/graph/__init__.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/graph/builder.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/graph/formatters.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/graph/merge.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/graph/models.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/graph/query.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/graph/serialization.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/lineage/__init__.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/lineage/analyzer.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/lineage/formatters.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/schema/__init__.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/schema/extractor.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/templating/__init__.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/templating/base.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/templating/jinja.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/templating/registry.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/templating/variables.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/utils/__init__.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/utils/config.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/utils/file_utils.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/src/sqlglider/utils/schema.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/__init__.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/multi_file_queries/analytics_pipeline.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/multi_file_queries/analytics_pipeline_union_merge.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/multi_file_queries/customers.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/multi_file_queries/orders.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/multi_file_queries/reports.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/multi_file_queries/view_based_merge.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/original_queries/test_cte.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/original_queries/test_cte_query.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/original_queries/test_cte_view_star.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/original_queries/test_generated_column_query.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/original_queries/test_multi.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/original_queries/test_multi_query.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/original_queries/test_single_query.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/original_queries/test_subquery.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/original_queries/test_tables.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/original_queries/test_view.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/original_queries/test_view_window_cte.sql +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/fixtures/sample_manifest.csv +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/__init__.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/catalog/__init__.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/catalog/test_base.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/catalog/test_databricks.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/catalog/test_registry.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/dissection/__init__.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/dissection/test_analyzer.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/dissection/test_formatters.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/dissection/test_models.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/graph/__init__.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/graph/test_builder.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/graph/test_formatters.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/graph/test_merge.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/graph/test_models.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/graph/test_query.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/graph/test_serialization.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/lineage/__init__.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/lineage/test_analyzer.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/lineage/test_formatters.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/schema/__init__.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/schema/test_extractor.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/templating/__init__.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/templating/test_base.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/templating/test_jinja.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/templating/test_registry.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/templating/test_variables.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/test_cli.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/utils/__init__.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/utils/test_config.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/utils/test_file_utils.py +0 -0
- {sql_glider-0.1.20 → sql_glider-0.1.23}/tests/sqlglider/utils/test_schema.py +0 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths:
|
|
7
|
+
- "docs/**"
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
pages: write
|
|
13
|
+
id-token: write
|
|
14
|
+
|
|
15
|
+
concurrency:
|
|
16
|
+
group: pages
|
|
17
|
+
cancel-in-progress: true
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
build:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- name: Install uv
|
|
26
|
+
uses: astral-sh/setup-uv@v4
|
|
27
|
+
with:
|
|
28
|
+
version: "latest"
|
|
29
|
+
|
|
30
|
+
- name: Set up Python
|
|
31
|
+
run: uv python install 3.11
|
|
32
|
+
|
|
33
|
+
- name: Install dependencies
|
|
34
|
+
run: uv sync --group docs
|
|
35
|
+
|
|
36
|
+
- name: Build docs
|
|
37
|
+
run: uv run zensical build
|
|
38
|
+
working-directory: docs
|
|
39
|
+
|
|
40
|
+
- name: Upload Pages artifact
|
|
41
|
+
uses: actions/upload-pages-artifact@v3
|
|
42
|
+
with:
|
|
43
|
+
path: docs/site
|
|
44
|
+
|
|
45
|
+
deploy:
|
|
46
|
+
needs: build
|
|
47
|
+
runs-on: ubuntu-latest
|
|
48
|
+
environment:
|
|
49
|
+
name: github-pages
|
|
50
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
51
|
+
steps:
|
|
52
|
+
- name: Deploy to GitHub Pages
|
|
53
|
+
id: deployment
|
|
54
|
+
uses: actions/deploy-pages@v4
|
|
@@ -23,6 +23,7 @@ sql-glider/
|
|
|
23
23
|
│ │ ├── builder.py # GraphBuilder for creating graphs from SQL
|
|
24
24
|
│ │ ├── merge.py # GraphMerger for combining graphs
|
|
25
25
|
│ │ ├── query.py # GraphQuerier for upstream/downstream analysis
|
|
26
|
+
│ │ ├── diagram_formatters.py # Mermaid and DOT diagram output formatters
|
|
26
27
|
│ │ └── serialization.py # JSON save/load, rustworkx conversion
|
|
27
28
|
│ ├── lineage/
|
|
28
29
|
│ │ ├── __init__.py # Lineage module exports
|
|
@@ -447,6 +448,15 @@ sqlglider graph merge --glob "*.json" -o merged.json
|
|
|
447
448
|
# Query lineage
|
|
448
449
|
sqlglider graph query graph.json --upstream orders.customer_id
|
|
449
450
|
sqlglider graph query graph.json --downstream customers.id -f json
|
|
451
|
+
|
|
452
|
+
# Query with diagram output (Mermaid or DOT)
|
|
453
|
+
sqlglider graph query graph.json --upstream orders.customer_id -f mermaid
|
|
454
|
+
sqlglider graph query graph.json --downstream customers.id -f dot
|
|
455
|
+
|
|
456
|
+
# Visualize entire graph as diagram
|
|
457
|
+
sqlglider graph visualize graph.json # Mermaid (default)
|
|
458
|
+
sqlglider graph visualize graph.json -f dot # DOT/Graphviz
|
|
459
|
+
sqlglider graph visualize graph.json -o lineage.mmd
|
|
450
460
|
```
|
|
451
461
|
|
|
452
462
|
### 5. Dissection Module (`dissection/`)
|
|
@@ -67,6 +67,7 @@ src/sqlglider/
|
|
|
67
67
|
│ ├── builder.py # Build lineage graphs from SQL files
|
|
68
68
|
│ ├── merge.py # Merge multiple graphs
|
|
69
69
|
│ ├── query.py # Query upstream/downstream lineage
|
|
70
|
+
│ ├── diagram_formatters.py # Mermaid and DOT diagram output formatters
|
|
70
71
|
│ ├── models.py # Graph data models (Pydantic)
|
|
71
72
|
│ └── serialization.py # JSON save/load for graphs
|
|
72
73
|
├── lineage/
|
|
@@ -268,6 +269,22 @@ uv run sqlglider graph query graph.json --upstream orders.total -f json
|
|
|
268
269
|
|
|
269
270
|
# Query with CSV output
|
|
270
271
|
uv run sqlglider graph query graph.json --downstream customers.id -f csv
|
|
272
|
+
|
|
273
|
+
# Query with Mermaid diagram output
|
|
274
|
+
uv run sqlglider graph query graph.json --upstream orders.total -f mermaid
|
|
275
|
+
|
|
276
|
+
# Query with DOT (Graphviz) diagram output
|
|
277
|
+
uv run sqlglider graph query graph.json --downstream customers.id -f dot
|
|
278
|
+
|
|
279
|
+
# Visualize entire graph as Mermaid diagram
|
|
280
|
+
uv run sqlglider graph visualize graph.json
|
|
281
|
+
|
|
282
|
+
# Visualize entire graph as DOT diagram
|
|
283
|
+
uv run sqlglider graph visualize graph.json -f dot
|
|
284
|
+
|
|
285
|
+
# Save diagram to file
|
|
286
|
+
uv run sqlglider graph visualize graph.json -o lineage.mmd
|
|
287
|
+
uv run sqlglider graph visualize graph.json -f dot -o lineage.dot
|
|
271
288
|
```
|
|
272
289
|
|
|
273
290
|
### SQL Templating
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sql-glider
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.23
|
|
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/
|
|
@@ -32,8 +32,12 @@ Description-Content-Type: text/markdown
|
|
|
32
32
|
|
|
33
33
|
# SQL Glider
|
|
34
34
|
|
|
35
|
+

|
|
36
|
+
|
|
35
37
|
SQL Utility Toolkit for better understanding, use, and governance of your queries in a native environment.
|
|
36
38
|
|
|
39
|
+
**[Read the docs](https://rycowhi.github.io/sql-glider/)**
|
|
40
|
+
|
|
37
41
|
## Overview
|
|
38
42
|
|
|
39
43
|
SQL Glider provides powerful column-level and table-level lineage analysis for SQL queries using SQLGlot. It operates on standalone SQL files without requiring a full project setup, making it perfect for ad-hoc analysis, data governance, and understanding query dependencies.
|
|
@@ -409,6 +413,17 @@ uv run sqlglider graph query graph.json --upstream orders.customer_id
|
|
|
409
413
|
|
|
410
414
|
# Query downstream dependencies (find all columns affected by a source)
|
|
411
415
|
uv run sqlglider graph query graph.json --downstream customers.id
|
|
416
|
+
|
|
417
|
+
# Query with Mermaid diagram output
|
|
418
|
+
uv run sqlglider graph query graph.json --upstream orders.customer_id -f mermaid
|
|
419
|
+
|
|
420
|
+
# Query with DOT (Graphviz) diagram output
|
|
421
|
+
uv run sqlglider graph query graph.json --downstream customers.id -f dot
|
|
422
|
+
|
|
423
|
+
# Visualize entire graph as a diagram
|
|
424
|
+
uv run sqlglider graph visualize graph.json # Mermaid (default)
|
|
425
|
+
uv run sqlglider graph visualize graph.json -f dot # DOT/Graphviz
|
|
426
|
+
uv run sqlglider graph visualize graph.json -o lineage.mmd # Save to file
|
|
412
427
|
```
|
|
413
428
|
|
|
414
429
|
**Example Upstream Query Output:**
|
|
@@ -796,6 +811,31 @@ src/sqlglider/
|
|
|
796
811
|
└── file_utils.py # File I/O utilities
|
|
797
812
|
```
|
|
798
813
|
|
|
814
|
+
## Documentation
|
|
815
|
+
|
|
816
|
+
Project documentation is built with [Zensical](https://zensical.org/) and lives in the `docs/` directory:
|
|
817
|
+
|
|
818
|
+
```
|
|
819
|
+
docs/
|
|
820
|
+
├── zensical.toml # Site configuration (name, theme, features)
|
|
821
|
+
└── docs/ # Markdown content
|
|
822
|
+
└── index.md # Landing page
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
To preview docs locally:
|
|
826
|
+
|
|
827
|
+
```bash
|
|
828
|
+
cd docs && uv run zensical serve
|
|
829
|
+
```
|
|
830
|
+
|
|
831
|
+
To build the static site:
|
|
832
|
+
|
|
833
|
+
```bash
|
|
834
|
+
cd docs && uv run zensical build
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
The built site outputs to `docs/site/` (git-ignored). Documentation is automatically deployed to GitHub Pages on pushes to `main` via the `docs.yml` workflow.
|
|
838
|
+
|
|
799
839
|
## Publishing
|
|
800
840
|
|
|
801
841
|
SQL Glider is configured for publishing to both TestPyPI and PyPI using `uv`.
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
# SQL Glider
|
|
2
2
|
|
|
3
|
+

|
|
4
|
+
|
|
3
5
|
SQL Utility Toolkit for better understanding, use, and governance of your queries in a native environment.
|
|
4
6
|
|
|
7
|
+
**[Read the docs](https://rycowhi.github.io/sql-glider/)**
|
|
8
|
+
|
|
5
9
|
## Overview
|
|
6
10
|
|
|
7
11
|
SQL Glider provides powerful column-level and table-level lineage analysis for SQL queries using SQLGlot. It operates on standalone SQL files without requiring a full project setup, making it perfect for ad-hoc analysis, data governance, and understanding query dependencies.
|
|
@@ -377,6 +381,17 @@ uv run sqlglider graph query graph.json --upstream orders.customer_id
|
|
|
377
381
|
|
|
378
382
|
# Query downstream dependencies (find all columns affected by a source)
|
|
379
383
|
uv run sqlglider graph query graph.json --downstream customers.id
|
|
384
|
+
|
|
385
|
+
# Query with Mermaid diagram output
|
|
386
|
+
uv run sqlglider graph query graph.json --upstream orders.customer_id -f mermaid
|
|
387
|
+
|
|
388
|
+
# Query with DOT (Graphviz) diagram output
|
|
389
|
+
uv run sqlglider graph query graph.json --downstream customers.id -f dot
|
|
390
|
+
|
|
391
|
+
# Visualize entire graph as a diagram
|
|
392
|
+
uv run sqlglider graph visualize graph.json # Mermaid (default)
|
|
393
|
+
uv run sqlglider graph visualize graph.json -f dot # DOT/Graphviz
|
|
394
|
+
uv run sqlglider graph visualize graph.json -o lineage.mmd # Save to file
|
|
380
395
|
```
|
|
381
396
|
|
|
382
397
|
**Example Upstream Query Output:**
|
|
@@ -764,6 +779,31 @@ src/sqlglider/
|
|
|
764
779
|
└── file_utils.py # File I/O utilities
|
|
765
780
|
```
|
|
766
781
|
|
|
782
|
+
## Documentation
|
|
783
|
+
|
|
784
|
+
Project documentation is built with [Zensical](https://zensical.org/) and lives in the `docs/` directory:
|
|
785
|
+
|
|
786
|
+
```
|
|
787
|
+
docs/
|
|
788
|
+
├── zensical.toml # Site configuration (name, theme, features)
|
|
789
|
+
└── docs/ # Markdown content
|
|
790
|
+
└── index.md # Landing page
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
To preview docs locally:
|
|
794
|
+
|
|
795
|
+
```bash
|
|
796
|
+
cd docs && uv run zensical serve
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
To build the static site:
|
|
800
|
+
|
|
801
|
+
```bash
|
|
802
|
+
cd docs && uv run zensical build
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
The built site outputs to `docs/site/` (git-ignored). Documentation is automatically deployed to GitHub Pages on pushes to `main` via the `docs.yml` workflow.
|
|
806
|
+
|
|
767
807
|
## Publishing
|
|
768
808
|
|
|
769
809
|
SQL Glider is configured for publishing to both TestPyPI and PyPI using `uv`.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Documentation
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches:
|
|
5
|
+
- master
|
|
6
|
+
- main
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
pages: write
|
|
10
|
+
id-token: write
|
|
11
|
+
jobs:
|
|
12
|
+
deploy:
|
|
13
|
+
environment:
|
|
14
|
+
name: github-pages
|
|
15
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/configure-pages@v5
|
|
19
|
+
- uses: actions/checkout@v5
|
|
20
|
+
- uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: 3.x
|
|
23
|
+
- run: pip install zensical
|
|
24
|
+
- run: zensical build --clean
|
|
25
|
+
- uses: actions/upload-pages-artifact@v4
|
|
26
|
+
with:
|
|
27
|
+
path: site
|
|
28
|
+
- uses: actions/deploy-pages@v4
|
|
29
|
+
id: deployment
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
---
|
|
2
|
+
icon: lucide/database
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Catalogs
|
|
6
|
+
|
|
7
|
+
SQL Glider can connect to remote data catalogs to pull DDL definitions for the tables referenced in your SQL. This is useful when you want to enrich lineage analysis with real schema information, validate queries against production table definitions, or simply collect DDL for documentation.
|
|
8
|
+
|
|
9
|
+
## How It Works
|
|
10
|
+
|
|
11
|
+
The `tables pull` command reads your SQL, extracts the table names, then fetches the `CREATE TABLE` DDL for each one from a remote catalog. CTEs are automatically excluded since they don't exist in any remote catalog.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Pull DDL for all tables referenced in a query
|
|
15
|
+
sqlglider tables pull query.sql --catalog-type databricks
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Output:
|
|
19
|
+
|
|
20
|
+
```sql
|
|
21
|
+
-- Table: my_catalog.my_schema.customers
|
|
22
|
+
CREATE TABLE my_catalog.my_schema.customers (
|
|
23
|
+
customer_id BIGINT,
|
|
24
|
+
name STRING,
|
|
25
|
+
email STRING,
|
|
26
|
+
created_at TIMESTAMP
|
|
27
|
+
)
|
|
28
|
+
USING DELTA;
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
You can also write each table's DDL to a separate file:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
sqlglider tables pull query.sql -c databricks -o ./ddl/
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This creates one `.sql` file per table in the `./ddl/` directory.
|
|
38
|
+
|
|
39
|
+
## Built-in: Databricks
|
|
40
|
+
|
|
41
|
+
SQL Glider ships with a Databricks Unity Catalog provider. It requires the Databricks SDK as an optional dependency:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install sql-glider[databricks]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Authentication
|
|
48
|
+
|
|
49
|
+
The Databricks catalog uses the Databricks SDK's unified authentication, which tries the following sources in order:
|
|
50
|
+
|
|
51
|
+
1. Explicit host and token from `sqlglider.toml`
|
|
52
|
+
2. Environment variables (`DATABRICKS_HOST`, `DATABRICKS_TOKEN`)
|
|
53
|
+
3. Databricks CLI profile (`~/.databrickscfg`)
|
|
54
|
+
4. OAuth M2M via `DATABRICKS_CLIENT_ID` / `DATABRICKS_CLIENT_SECRET`
|
|
55
|
+
5. Azure CLI or Google Cloud auth for cloud-hosted workspaces
|
|
56
|
+
|
|
57
|
+
A **warehouse ID** is always required. Set it in config or via the `DATABRICKS_WAREHOUSE_ID` environment variable.
|
|
58
|
+
|
|
59
|
+
### Configuration
|
|
60
|
+
|
|
61
|
+
Configure Databricks in `sqlglider.toml`:
|
|
62
|
+
|
|
63
|
+
```toml
|
|
64
|
+
[sqlglider]
|
|
65
|
+
catalog_type = "databricks"
|
|
66
|
+
|
|
67
|
+
[sqlglider.catalog.databricks]
|
|
68
|
+
warehouse_id = "abc123def456"
|
|
69
|
+
profile = "my-workspace" # optional: Databricks CLI profile
|
|
70
|
+
host = "https://my.databricks.com" # optional if using profile or env vars
|
|
71
|
+
token = "dapi..." # optional: prefer OAuth or profile instead
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Or use environment variables:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
export DATABRICKS_HOST="https://my.databricks.com"
|
|
78
|
+
export DATABRICKS_TOKEN="dapi..."
|
|
79
|
+
export DATABRICKS_WAREHOUSE_ID="abc123def456"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Usage
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Pull DDL to stdout
|
|
86
|
+
sqlglider tables pull query.sql -c databricks
|
|
87
|
+
|
|
88
|
+
# Pull DDL to folder
|
|
89
|
+
sqlglider tables pull query.sql -c databricks -o ./ddl/
|
|
90
|
+
|
|
91
|
+
# Combine with templating
|
|
92
|
+
sqlglider tables pull query.sql -c databricks --templater jinja --var schema=prod
|
|
93
|
+
|
|
94
|
+
# From stdin
|
|
95
|
+
echo "SELECT * FROM my_catalog.my_schema.users" | sqlglider tables pull -c databricks
|
|
96
|
+
|
|
97
|
+
# List available catalog providers
|
|
98
|
+
sqlglider tables pull --list
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Writing a Custom Catalog Provider
|
|
102
|
+
|
|
103
|
+
You can create your own catalog provider as a Python package and register it as a plugin.
|
|
104
|
+
|
|
105
|
+
### 1. Implement the Catalog Class
|
|
106
|
+
|
|
107
|
+
Subclass `sqlglider.catalog.base.Catalog` and implement three methods:
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from typing import Any, Dict, List, Optional
|
|
111
|
+
|
|
112
|
+
from sqlglider.catalog.base import Catalog, CatalogError
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class SnowflakeCatalog(Catalog):
|
|
116
|
+
@property
|
|
117
|
+
def name(self) -> str:
|
|
118
|
+
return "snowflake"
|
|
119
|
+
|
|
120
|
+
def configure(self, config: Optional[Dict[str, Any]] = None) -> None:
|
|
121
|
+
"""Set up connection details from config or environment."""
|
|
122
|
+
config = config or {}
|
|
123
|
+
self._account = config.get("account")
|
|
124
|
+
self._warehouse = config.get("warehouse")
|
|
125
|
+
# Validate required settings
|
|
126
|
+
if not self._account:
|
|
127
|
+
raise CatalogError("Snowflake account is required")
|
|
128
|
+
|
|
129
|
+
def get_ddl(self, table_name: str) -> str:
|
|
130
|
+
"""Fetch DDL for a single table."""
|
|
131
|
+
try:
|
|
132
|
+
# Connect and run: GET_DDL('TABLE', table_name)
|
|
133
|
+
return ddl_string
|
|
134
|
+
except Exception as e:
|
|
135
|
+
raise CatalogError(f"Failed to fetch DDL for {table_name}: {e}") from e
|
|
136
|
+
|
|
137
|
+
def get_ddl_batch(self, table_names: List[str]) -> Dict[str, str]:
|
|
138
|
+
"""Fetch DDL for multiple tables.
|
|
139
|
+
|
|
140
|
+
Return a dict mapping table names to DDL strings.
|
|
141
|
+
For tables that fail, prefix the value with "ERROR: ".
|
|
142
|
+
"""
|
|
143
|
+
results: Dict[str, str] = {}
|
|
144
|
+
for table in table_names:
|
|
145
|
+
try:
|
|
146
|
+
results[table] = self.get_ddl(table)
|
|
147
|
+
except CatalogError as e:
|
|
148
|
+
results[table] = f"ERROR: {e}"
|
|
149
|
+
return results
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Key points:
|
|
153
|
+
|
|
154
|
+
- **`name`** — the identifier users pass to `--catalog-type`
|
|
155
|
+
- **`configure()`** — called after instantiation with settings from `sqlglider.toml` and CLI; validate required config here
|
|
156
|
+
- **`get_ddl()`** — fetch DDL for one table; raise `CatalogError` on failure
|
|
157
|
+
- **`get_ddl_batch()`** — fetch DDL for many tables; prefix failures with `"ERROR: "` so the batch continues
|
|
158
|
+
|
|
159
|
+
### 2. Register via Entry Points
|
|
160
|
+
|
|
161
|
+
In your package's `pyproject.toml`:
|
|
162
|
+
|
|
163
|
+
```toml
|
|
164
|
+
[project.entry-points."sqlglider.catalogs"]
|
|
165
|
+
snowflake = "my_package.catalog:SnowflakeCatalog"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### 3. Add Configuration Support
|
|
169
|
+
|
|
170
|
+
Users can configure your catalog in `sqlglider.toml`. The config section name matches the catalog name:
|
|
171
|
+
|
|
172
|
+
```toml
|
|
173
|
+
[sqlglider]
|
|
174
|
+
catalog_type = "snowflake"
|
|
175
|
+
|
|
176
|
+
[sqlglider.catalog.snowflake]
|
|
177
|
+
account = "xy12345.us-east-1"
|
|
178
|
+
warehouse = "COMPUTE_WH"
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
!!! note
|
|
182
|
+
For the config section to be loaded automatically, the core `ConfigSettings` model needs to know about your provider. For third-party plugins, users can also pass configuration through environment variables in your `configure()` method.
|
|
183
|
+
|
|
184
|
+
### 4. Use It
|
|
185
|
+
|
|
186
|
+
After installing your package:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
sqlglider tables pull query.sql --catalog-type snowflake
|
|
190
|
+
```
|