Skip to navigation

Snowflake Connector

View as Markdown

There are two ways to use Snowflake data: sample it in place with SnowflakeSource, or read a table into memory with read() and build the schema from DataFrames. Prefer SnowflakeSource for warehouse-sized tables — materialize() queries only the rows a prediction needs, rather than reading a whole table. (Building the schema itself still runs lightweight metadata and preview queries — see Build a Schema.)

Installation

pip install "structured-data-models-client[relational,snowflake]"

Sample in place with SnowflakeSource

import snowflake.connector
from sdm_client import PredictiveQuery, Schema
from sdm_connectors import SnowflakeSource
connection = snowflake.connector.connect(
account="my_account", user="my_user", password="...", warehouse="my_warehouse",
)
source = SnowflakeSource(connection, database="MY_DATABASE", schema="MY_SCHEMA")
schema = Schema.from_source(
source,
{"users": "USERS", "orders": "ORDERS"},
time_columns={"orders": "ORDER_TIME"},
)
request = PredictiveQuery(
"PREDICT COUNT(orders.*, 0, 30, days) FOR EACH users.USER_ID", schema
).materialize(indices=[7, 12, 3])

tables maps the table names your query uses to the names in Snowflake — {"users": "USERS"} lets you write users in PQL for Snowflake’s USERS table. Column names are not renamed and PQL matches them case-sensitively, so if Snowflake reports a column as USER_ID (the default for an unquoted identifier), reference it as users.USER_ID, not users.user_id. Quote the identifier in PQL if you need a different case: users.`user_id`.

The connection is yours — SnowflakeSource never closes it; close it when you are done sampling. A Snowpark session works too; it is reached through its own connector connection.

Columns, keys, and relationships come from Snowflake’s own constraints where it declares any, and from the same name-matching inference as Schema.from_data() otherwise. Because Snowflake does not enforce a declared key, each key is checked against every row with one aggregate query per table; pass check_keys=False to skip that when the key is already trusted.

Snowflake semantic views

A Snowflake semantic view already states its tables, joins, and columns. Convert it directly:

schema = Schema.from_source(source.semantic_model("sales_metrics"))

Its expressions run as SQL under your own credentials, so by default only pure, deterministic built-in functions are allowed; pass trust_expressions=True on semantic_model(...) to keep an expression that calls something else, when you trust whoever wrote the view. schema.conversion_notes lists what the conversion resolved, for a person to read — its wording is not part of the contract.

Read into memory instead

from sdm_connectors import read
from sdm_client import Schema
users = read(
"snowflake",
account="my_account", user="my_user", password="...", warehouse="my_warehouse",
table="USERS",
)
orders = read("snowflake", account="my_account", user="my_user", password="...", warehouse="my_warehouse", table="ORDERS")
schema = Schema.from_data({"users": users, "orders": orders})

Use a secret manager or environment variable for credentials; do not store passwords in source files or notebooks. In a Snowflake notebook with an active Snowpark session, omit authentication arguments and read() reuses that session.

Review the inferred schema and relationships before predicting — see Build a Schema.