Skip to content

[DBA-297] Fix Snowflake adapter to use secret in ATTACH instead of connection string#274

Merged
Lenar (catstrike) merged 6 commits into
mainfrom
ls/fix-snowflake-adapter
Mar 30, 2026
Merged

[DBA-297] Fix Snowflake adapter to use secret in ATTACH instead of connection string#274
Lenar (catstrike) merged 6 commits into
mainfrom
ls/fix-snowflake-adapter

Conversation

@catstrike
Copy link
Copy Markdown
Collaborator

Summary

The Snowflake adapter created a DuckDB secret via CREATE OR REPLACE SECRET but the ATTACH statement ignored it, passing credentials directly via a connection string instead. The secret was effectively dead code.

Changes

Fix: Wire DuckDB secret into ATTACH statement

Replaced the connection-string-based ATTACH flow with a secret-based one:

Before (buggy):

ATTACH '<account=...;password=...>' AS "name" (TYPE snowflake, READ_ONLY);
CREATE OR REPLACE SECRET "name" (TYPE snowflake, ...);  -- unused!

After (fixed):

CREATE OR REPLACE SECRET "name" (TYPE snowflake, account '...', user '...', ...);
ATTACH '' AS "name" (TYPE snowflake, SECRET "name", READ_ONLY);
Affected files
  • databao/agent/databases/snowflake_adapter.py
  • examples/snowflake-example.py
  • tests/test_snowflake_adapter.py

Refactoring

  • Removed _create_connection_string (no longer needed)
  • Renamed _create_secret_sql_create_secret_params (returns a dict instead of raw SQL)
  • Extracted SQL formatting into _format_sql_params helper
  • Updated all tests to use _create_secret_params directly

Test Plan

  • All existing Snowflake adapter tests updated and passing
  • Covers password, key-pair (inline + file), SSO (externalbrowser, Okta, OAuth) auth types
  • Error handling tests for missing keys and unreadable files

YouTrack

DBA-297

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes the Snowflake → DuckDB registration path so DuckDB’s Snowflake SECRET is actually used by ATTACH, instead of embedding credentials in the connection string (which made the secret unused).

Changes:

  • Switch Snowflake DuckDB registration from connection-string ATTACH to CREATE OR REPLACE SECRET + ATTACH ... SECRET.
  • Refactor secret creation to return params dict (_create_secret_params) and add _format_sql_params for SQL rendering.
  • Update Snowflake adapter tests and the Snowflake example script to match the new flow.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
databao/agent/databases/snowflake_adapter.py Wire DuckDB secret into Snowflake ATTACH; refactor secret param generation/formatting.
tests/test_snowflake_adapter.py Update tests to assert secret params dict instead of parsing generated SQL.
examples/snowflake-example.py Update connection URL and simplify domain creation to match current usage.
Comments suppressed due to low confidence (1)

databao/agent/databases/snowflake_adapter.py:146

  • config.additional_properties is no longer propagated when registering the Snowflake connection in DuckDB. Previously _create_connection_string merged **config.additional_properties, so extra Snowflake connector options (e.g., session/timeout settings) would be honored; with the secret-based flow they’re silently dropped, which is a functional regression for users relying on them. Consider merging config.additional_properties into the secret params (casting values to strings as needed) or passing them via the ATTACH options if DuckDB expects them there.
    def _create_secret_params(config: SnowflakeConnectionProperties) -> dict[str, str]:
        params: dict[str, str] = {
            ACCOUNT_KEY: config.account,
        }
        if config.user:
            params[USER_KEY] = config.user
        if config.database:
            params[DATABASE_KEY] = config.database
        if config.warehouse:
            params[WAREHOUSE_KEY] = config.warehouse
        if config.role:
            params["role"] = config.role


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread databao/agent/databases/snowflake_adapter.py Outdated
Comment thread tests/test_snowflake_adapter.py
Comment thread tests/test_snowflake_adapter.py
Comment thread examples/snowflake-example.py
Copilot AI review requested due to automatic review settings March 30, 2026 20:02
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread databao/agent/databases/snowflake_adapter.py
@catstrike Lenar (catstrike) merged commit ba9efc5 into main Mar 30, 2026
8 checks passed
@catstrike Lenar (catstrike) deleted the ls/fix-snowflake-adapter branch March 30, 2026 20:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants