-
Notifications
You must be signed in to change notification settings - Fork 25
feat: Add Snowflake Semantic Views support #200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
0a430fb to
53bd167
Compare
Add automatic detection and context injection for Snowflake Semantic Views
when a Snowflake connection is provided. This helps LLMs generate correct
queries using the SEMANTIC_VIEW() function with certified business metrics.
Changes:
- Add SnowflakeSource class (Python and R) that extends SQLAlchemySource/DBISource
- Discover semantic views via SHOW SEMANTIC VIEWS at initialization
- Retrieve DDL definitions via GET_DDL('SEMANTIC_VIEW', ...)
- Include semantic view context in schema output
- Add SEMANTIC_VIEW() syntax reference to system prompt
- Add Snowflake-specific SQL tips (QUALIFY, LATERAL FLATTEN, time travel)
- Graceful fallback when no semantic views exist or discovery fails
Based on the Snowflake skill from posit-dev/databot#278.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix SQL injection risk by escaping single quotes in view names - Add discover_semantic_views parameter for lazy initialization - Remove error swallowing, let errors propagate for debugging - Add debug logging when no semantic views are found - Move logger placement to top of file (Python) - Add defensive dialect check in normalize_data_source (Python) - Add comprehensive unit tests for both Python and R Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Introduces a Protocol-based adapter pattern for Snowflake semantic view discovery that works with both SQLAlchemy and Ibis backends: - Add _snowflake.py with RawSQLExecutor Protocol, executor implementations (SQLAlchemyExecutor, IbisExecutor), and standalone discovery functions - Add _snowflake_sources.py with SnowflakeSource and new SnowflakeIbisSource - Update normalize_data_source() to route Ibis Snowflake backends - Maintain backwards-compatible imports from _datasource.py This enables semantic view support for Ibis connections to Snowflake, not just SQLAlchemy connections. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
93ed750 to
83c271a
Compare
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
6aed7df to
42b8ece
Compare
Instead of separate SnowflakeSource and SnowflakeIbisSource classes, SQLAlchemySource and IbisSource now auto-detect Snowflake backends and discover semantic views during initialization. Changes: - SQLAlchemySource/IbisSource check dialect/backend name for "snowflake" - Discovery can be disabled via QUERYCHAT_DISABLE_SEMANTIC_VIEWS env var - Removed _snowflake_sources.py (no longer needed) - Simplified normalize_data_source() - no Snowflake-specific routing - Updated tests to verify new architecture Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extract inline syntax documentation to `prompts/semantic-view-syntax.md` in both R and Python packages, making it language-agnostic and easier to maintain. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace Protocol/class-based OOP with functional approach using backend_type: Literal["sqlalchemy", "ibis"] discriminator - Move env var check (QUERYCHAT_DISABLE_SEMANTIC_VIEWS) into discover_semantic_views() for early exit - Move semantic view discovery from __init__ to get_schema() for lazy initialization - Remove SemanticViewMixin in favor of direct function calls - Update tests to verify new lazy discovery behavior Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Snowflake SQL Tips section isn't necessary for semantic views support.
Removed the {{#is_snowflake}} block from prompt templates and the
is_snowflake variable from system prompt code in both R and Python.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace backend_type: Literal["sqlalchemy", "ibis"] parameter with isinstance(backend, sqlalchemy.Engine) checks for cleaner API. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The `backend.sql()` method in Ibis parses queries with sqlglot, which doesn't support Snowflake commands like `SHOW SEMANTIC VIEWS`. Switch to using `backend.raw_sql()` which executes queries without parsing. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove comment about raw_sql() per PR feedback - Add type ignore for raw_sql() to fix pyright error (method exists on concrete backends but not typed on SQLBackend base class) - Remove unused PROMPTS_DIR constant per PR feedback Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rename get_semantic_views_section() to get_semantic_views_description() on DataSource classes (clearer intent) - Rename get_semantic_views_section() to format_semantic_views() in _snowflake.py / DBISource.R (matches other format_* functions) - Update tests to use new method names Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Minimize diff by reverting auto-formatter changes that were not part of the semantic views feature. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update get_semantic_views_description() docstrings to clarify purpose - Revert list comprehension formatting to match original style Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Minimize diff by reverting air format changes that were not part of the semantic views feature. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Adds support for Snowflake Semantic Views by helping the LLM generate correct queries via the
SEMANTIC_VIEW()table function with certified business metrics.Features
SHOW SEMANTIC VIEWSGET_DDL('SEMANTIC_VIEW', ...)to understand available metrics, dimensions, and filtersSEMANTIC_VIEW()syntax reference in the system promptWhy Semantic Views matter
Raw table queries can return incorrect results when business logic isn't properly applied. For example, querying raw tables for "external customer revenue" returned $184B while the semantic model's certified metric returned $84.5B (the correct answer). The raw query was 2x+ too high because it ignored discounts and included invalid transaction codes.
Implementation
Python
SQLAlchemySourceandIbisSourcegainget_semantic_views_description()method_snowflake.pymodule withdiscover_semantic_views()andformat_semantic_views()prompts/semantic-views/directoryR
DBISourcegainsget_semantic_views_description()methodis_snowflake_connection()inst/prompts/semantic-views/directoryReferences
Based on the Snowflake skill from https://github.com/posit-dev/databot/pull/278