Skip to content

Snowflake

Configuration

warehouse:
  type: snowflake
  account: myorg-myaccount     # e.g. xy12345.us-east-1
  user: KELPMESH_USER
  password: "{{ env_var('SNOWFLAKE_PASSWORD') }}"
  role: TRANSFORMER             # optional
  warehouse: COMPUTE_WH         # Snowflake virtual warehouse
  database: ANALYTICS
  schema: PUBLIC                # optional
  threads: 8

Install dependencies

pip install snowflake-connector-python
warehouse:
  type: snowflake
  account: myorg-myaccount
  user: KELPMESH_USER
  private_key_path: /path/to/rsa_key.p8
  role: TRANSFORMER
  warehouse: COMPUTE_WH
  database: ANALYTICS

Generate a key pair:

openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt
openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub

Register the public key in Snowflake:

ALTER USER KELPMESH_USER SET RSA_PUBLIC_KEY='MIIBIjANBgkq...';

User permissions

CREATE ROLE KELPMESH_ROLE;
GRANT ROLE KELPMESH_ROLE TO USER KELPMESH_USER;
GRANT USAGE ON WAREHOUSE COMPUTE_WH TO ROLE KELPMESH_ROLE;
GRANT USAGE ON DATABASE ANALYTICS TO ROLE KELPMESH_ROLE;
GRANT USAGE ON SCHEMA ANALYTICS.PUBLIC TO ROLE KELPMESH_ROLE;
GRANT CREATE TABLE ON SCHEMA ANALYTICS.PUBLIC TO ROLE KELPMESH_ROLE;
GRANT CREATE VIEW ON SCHEMA ANALYTICS.PUBLIC TO ROLE KELPMESH_ROLE;
GRANT SELECT ON ALL TABLES IN SCHEMA RAW.PUBLIC TO ROLE KELPMESH_ROLE;
GRANT SELECT ON FUTURE TABLES IN SCHEMA RAW.PUBLIC TO ROLE KELPMESH_ROLE;

Materialization support

Materialization Supported Notes
view CREATE OR REPLACE VIEW
table CREATE TABLE AS SELECT
incremental (append) INSERT INTO
incremental (merge) Snowflake MERGE INTO ... USING
ephemeral Inlined as CTE

Incremental merge example

-- {{ config(materialized="incremental", unique_key="customer_id", incremental_strategy="merge") }}
SELECT
  customer_id,
  email,
  plan,
  updated_at
FROM raw.customers
WHERE updated_at >= CURRENT_DATE - 7

KelpMesh generates a Snowflake MERGE statement:

MERGE INTO dim_customers AS target
USING (...) AS source
ON target."customer_id" = source."customer_id"
WHEN MATCHED THEN UPDATE SET target."email" = source."email", ...
WHEN NOT MATCHED THEN INSERT ("customer_id", "email", ...) VALUES (source."customer_id", ...)

Performance tips

  • Set threads: 8 or higher — Snowflake handles concurrency well.
  • Use AUTO_SUSPEND on your virtual warehouse to pause it when kelpmesh runs finish.
  • Tag your virtual warehouse with KelpMesh to separate compute costs from BI workloads.