Skip to main content

adding-new-adapters-support-for-dbt-query-profiling

Use when adding support for a new data warehouse adapter (e.g., Trino, Postgres, Spark) to dbt-query-profiler. Triggers include creating adapter macros, implementing query history/plan/stats, or extending platform support.

Zur Installation springen

Quellinformationen

Repository
dbt-labs/dbt-query-profiler
Letzte Quellaktivität
28. Juli 2026 um 13:08
Erkannte Sprache von SKILL.md
Englisch
Sterne
3
Forks
1

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
adding-new-adapters-support-for-dbt-query-profiling
description
Use when adding support for a new data warehouse adapter (e.g., Trino, Postgres, Spark) to dbt-query-profiler. Triggers include creating adapter macros, implementing query history/plan/stats, or extending platform support.
# Adding New Adapters to dbt-query-profiler ## Overview This package uses `adapter.dispatch()` to route calls to adapter-specific implementations. Adding a new adapter requires creating 5 macro files, implementing self-exclusion via `_self_identifier()`, updating documentation, and adding integration tests. ## File Structure Create these files for adapter `{adapter}`: ``` macros/{adapter}/ ├── query_history.sql # Required: query history access ├── query_sql.sql # Required: retrieve query text ├── query_plan.sql # Required: EXPLAIN-based plans (or raise error) ├── execution_plan.sql # Required: actual execution stats (or raise error) └── query_stats.sql # Required: execution statistics ``` ## Macro Naming Convention Each macro must follow the pattern `{adapter}__{macro_name}`: ```jinja2 {% macro trino__get_query_history(table_name, user_name, query_type, limit, result_limit) %} -- Adapter-specific implementation {% endmacro %} ``` ## Required Macros Per File ### query_history.sql - `{adapter}__get_query_history(table_name, user_name, query_type, limit, result_limit)` - `{adapter}__print_query_history(table_name, user_name, query_type, limit, result_limit)` ### query_sql.sql - `{adapter}__get_query_sql(query_id, result_limit=1000)` - `{adapter}__print_query_sql(query_id, result_limit=1000)` ### query_plan.sql - `{adapter}__get_query_plan(sql)` - `{adapter}__print_query_plan(sql, format)` ### execution_plan.sql - `{adapter}__get_execution_plan(query_id)` - `{adapter}__print_execution_plan(query_id, format)` - `{adapter}__get_execution_plan_summary(query_id)` (optional — if the adapter has no separate summary concept, delegate to `get_execution_plan`) ### query_stats.sql - `{adapter}__get_query_stats(query_id, format, result_limit)` - `{adapter}__print_query_stats(query_id, format, result_limit)` ## Self-Identifier Pattern (Critical) The `_self_identifier()` macro returns `'__dbt_query_profiler_self__'` and **must be used to exclude the profiler's own queries** from results. The identifier uses double underscores to avoid accidentally matching project names like `dbt_query_profiler_integration_tests`. ### Implementation Approaches **Option A: Query tags (preferred if supported)** ```jinja2 -- In get_query_history: exclude by tag where query_tag != '{{ dbt_query_profiler._self_identifier() }}' -- In print_query_history: set tag before executing {% do run_query("SET QUERY_TAG = '" ~ dbt_query_profiler._self_identifier() ~ "'") %} ``` **Option B: Query text filtering (fallback)** ```jinja2 -- In get_query_history: exclude by text pattern where query_text not like '%{{ dbt_query_profiler._self_identifier() }}%' -- In print_query_history: add comment to query {% set query %} /* {{ dbt_query_profiler._self_identifier() }} */ select ... {% endset %} ``` ### Existing Adapter Approaches | Adapter | Method | |---------|--------| | Snowflake | Query tags via `ALTER SESSION SET QUERY_TAG` | | BigQuery | Comment prefix in query text | | Databricks | Comment prefix in query text | | Redshift | Comment prefix in query text | | DuckDB | Comment prefix in query text | ## Return Value Standards ### get_* macros Return a SQL string that can be used in models: ```jinja2 {% macro adapter__get_query_history(...) %} select query_id, query_text, user_name, -- ... standard columns from system.query_history where ... {% endmacro %} ``` ### print_* macros Execute query and print results: ```jinja2 {% macro adapter__print_query_history(...) %} {# Set self-identifier first #} {% do run_query("/* " ~ dbt_query_profiler._self_identifier() ~ " */ SELECT 1") %} {% set query %} select array_agg(object_construct(*)) as result from ({{ dbt_query_profiler.get_query_history(...) }}) {% endset %} {% set results = run_query(query) %} {% if execute and results and results.rows and results.rows[0][0] %} {{ print(results.rows[0][0]) }} {{ return(results.rows[0][0]) }} {% else %} {{ print("No query found") }} {{ return(none) }} {% endif %} {% endmacro %} ``` ## Unsupported Features If a feature isn't available for the adapter, raise a clear error: ```jinja2 {% macro adapter__get_query_plan(query_id, format) %} {{ exceptions.raise_compiler_error( "get_query_plan is not supported for " ~ target.type ~ ". This adapter does not expose query execution plans." ) }} {% endmacro %} ``` ## Documentation Updates ### README.md 1. **Feature matrix** (lines 7-12): Add row for new adapter 2. **Permissions section**: Add subsection with required grants/roles 3. **Platform-Specific Notes**: Add subsection with behaviors, limitations, retention periods ### macros/schema.yml Add adapter name to "Supported adapters:" in each macro description: ```yaml - name: get_query_history description: | ... **Supported adapters:** Snowflake, BigQuery, Databricks, Redshift, DuckDB, {NewAdapter} ``` ## Integration Tests ### Location ``` integration_tests/ ├── models/setup/ │ └── setup_{adapter}.sql # If special initialization needed ├── tests/ │ └── (existing tests work via dispatch) └── dbt_project.yml # Update if hooks needed ``` ### Conditional Test Execution If a feature isn't supported, disable tests for that adapter: ```jinja2 {{ config( enabled=(target.type != 'your_adapter') ) }} ``` ### Setup Model (if needed) Some adapters require initialization (like DuckDB's logging): ```jinja2 -- models/setup/setup_adapter.sql {{ config( materialized='table', tags=['setup'] ) }} {% if execute %} {% do run_query("ADAPTER_SPECIFIC_SETUP_COMMAND") %} {% endif %} select 1 as setup_complete ``` ### On-Run-Start Hooks Add to `integration_tests/dbt_project.yml` if needed: ```yaml on-run-start: - "{{ dbt_query_profiler_integration_tests.enable_adapter_feature() }}" ``` ## Quick Reference: System Tables by Adapter | Adapter | Query History Source | |---------|---------------------| | Snowflake | `information_schema.query_history()` or `snowflake.account_usage.query_history` | | BigQuery | `INFORMATION_SCHEMA.JOBS_BY_USER` or `JOBS_BY_PROJECT` | | Databricks | `system.query.history` | | Redshift | `sys_query_history` | | DuckDB | `duckdb_logs` (requires `CALL enable_logging('QueryLog')`) | ## Checklist for New Adapter - [ ] Create `macros/{adapter}/query_history.sql` with get_ and print_ macros - [ ] Create `macros/{adapter}/query_sql.sql` with get_ and print_ macros - [ ] Create `macros/{adapter}/query_plan.sql` with get_ and print_ macros (EXPLAIN-based, or raise error) - [ ] Create `macros/{adapter}/execution_plan.sql` with get_, print_, and summary macros (or raise error) - [ ] Create `macros/{adapter}/query_stats.sql` with get_ and print_ macros - [ ] Implement `_self_identifier()` exclusion in all get_ macros - [ ] Add self-identifier tagging/commenting in all print_ macros - [ ] Update README.md feature matrix - [ ] Update README.md permissions section - [ ] Update README.md platform-specific notes - [ ] Update macros/schema.yml supported adapters lists - [ ] Add setup model if adapter needs initialization - [ ] Disable unsupported tests with `config(enabled=...)` - [ ] Test with `dbt run-operation dbt_query_profiler.print_query_history`
Auf GitHub ansehen