Declarative authoring¶
Each object in a declarative project is a single file under sources/, authored as YAML or
Python. This page covers how to author each object kind. For the project directory
structure, the manifest.yml schema, deployment targets, and templating, see
Declarative project configuration.
For the end-to-end workflow, see
Declarative feature store overview.
Author entities¶
An entity declares the join key that a feature view is grouped by. The same entity can be shared by many feature views.
YAML (sources/entities/USER_ID.yaml):
Python (sources/entities/user_id.py):
The order of join_keys matters: it sets the order in which the keys appear in the online
feature table’s primary key.
Author data sources¶
A source declares where feature data comes from. There are two kinds:
- A batch source reads from a Snowflake table or SQL query.
- A streaming source declares the schema of records pushed to the online service’s ingest endpoint.
Batch sources¶
A BatchSource must set exactly one of table, query, or query_file.
YAML (sources/datasources/EVENTS_BATCH_DECL.yaml):
Python (sources/datasources/events_batch_decl.py):
Use query for an inline SQL SELECT, or query_file to keep a long query in a sibling
.sql file (which also supports templating). In the Python form, pass query="SELECT ..."
in place of table=. Batch SQL supports -- single-line and /* ... */ block comments.
C-style // comments aren’t supported.
Streaming sources¶
A StreamingSource registers the schema of incoming records as metadata. It doesn’t create
a Snowflake table. The column set is also a runtime contract: the client-side preflight in
snow feature ingest rejects payloads that don’t match the registered columns before any
HTTP call.
YAML (sources/datasources/CLICKSTREAM_EVENTS.yaml):
Python (sources/datasources/clickstream_events.py):
REST is the only supported wire protocol today.
Author batch feature views¶
A batch feature view materializes features from a batch source into a
dynamic table that refreshes on a schedule. It can
be online (online: true, which also materializes an online feature table for
low-latency lookups) or offline-only (online: false, suitable for training-set
generation).
Passthrough feature view¶
The simplest batch feature view projects its source with no aggregation:
YAML (sources/feature_views/MY_BATCH_FV_BATCH_DECL.yaml):
Python (sources/feature_views/my_batch_fv_batch_decl.py) references the source object
directly:
refresh_freq sets the dynamic table refresh cadence (a duration such as "5 minutes" or a
CRON expression). target_lag sets the online feature table staleness target and is valid
only when online: true.
Tiled aggregation¶
To serve time-windowed aggregations, add a timestamp_col, declare the tile size with
feature_granularity, set feature_aggregation_method: tiles, and list the aggregation
features:
YAML (sources/feature_views/MY_ADV_BFV_DECL.yaml):
Python (sources/feature_views/my_adv_bfv_decl.py):
Aggregation features are validated at plan time, before any Snowflake call. Every feature
needs a function, a source_column, an output_column, and a window.
Append-only feature views¶
An append-only batch feature view retains history for point-in-time correct training-set
generation. Instead of overwriting the dynamic table on each refresh, it appends the current
contents to a companion snapshot table. Set append_only: true. This mode requires
refresh_mode: FULL, a CRON refresh_freq, and a timestamp_col, and it doesn’t support
tiled aggregation:
YAML (sources/feature_views/MY_APPEND_BFV_DECL.yaml):
Python (sources/feature_views/my_append_bfv_decl.py):
For training-only use with no online lookup, set online: false and drop target_lag
(it’s rejected on offline feature views). Everything else is unchanged.
Online compared to offline¶
The following table compares the two serving modes for a batch feature view:
| Aspect | online: true | online: false |
|---|---|---|
| Online feature table created? | Yes, queryable with snow feature query | No, only the offline dynamic table |
| Requires the online service? | Yes | No |
target_lag field | Allowed (online staleness) | Rejected at load time |
| Suitable for | Low-latency point lookups | Training-set generation |
| Usable in a feature group? | Yes | No |
Destructive compared to non-destructive edits¶
Operational edits apply in place through UPDATE_FV. Structural edits require a drop and
recreate through RECREATE_FV, which apply refuses without --destructive. The following
table lists how each kind of edit is planned:
| Edit | Plan operation | Destructive? |
|---|---|---|
refresh_freq, target_lag, warehouse, description | UPDATE_FV | No |
| Schema-preserving edit on a deployed append-only feature view | EVOLVE_FV | No, keeps snapshot history |
cluster_by, refresh_mode, aggregation features, source schema, append_only | RECREATE_FV | Yes |
| Removing the feature view file | DROP_FV | Yes |
Author streaming feature views¶
A streaming feature view computes features from a real-time push stream and serves them through a Postgres-backed online feature table. Records arrive on the online service’s ingest endpoint, flow through a pandas user-defined function, and materialize into tiled or continuous aggregations.
Streaming feature views are always online. Authoring online: false is rejected. A
streaming feature view binds an entity and a streaming source, declares a udf that
transforms incoming rows, and declares aggregation features:
YAML (sources/feature_views/USER_CLICK_STATS_DECL.yaml):
The udf.file value points at a sibling Python file containing the named transformation
function (sources/feature_views/USER_CLICK_STATS_DECL.py). The loader reads the file’s
source and inlines it as the UDF body:
The Python declarative form collapses the YAML and its sidecar UDF file into a single file, passing the transformation function as a callable:
The UDF’s signature is (df: pd.DataFrame) -> pd.DataFrame. It must be a named top-level
function (no lambdas, nested definitions, or class methods) and may import only from
numpy, pandas, re, and copy.
refresh_freq sets the cadence of the offline tile dynamic table and is required whenever a
feature declares a window. The online feature table itself always serves at 0-second lag,
so target_lag is rejected on streaming feature views. For continuous aggregation, set
feature_aggregation_method: continuous.
Changes to a streaming feature view’s transformation or aggregation schema can’t be patched
in place: they route through RECREATE_FV. Use versions (V1, V2) to roll out a breaking
change without disrupting active consumers.
Real-time feature views¶
Note
Real-time feature views can’t currently be authored, planned, or applied through the
declarative snow feature workflow. For a real-time push path today, use a streaming
feature view, which is the supported low-latency option. If you already rely on real-time
feature views, continue to register them through the imperative
snowflake.ml.feature_store API.
Feature groups¶
A feature group combines multiple online, Postgres-backed feature views into a single
online feature table. In the declarative workflow, a feature group is authored as a file
under sources/feature_groups/ that references each member by (name, version). Members
must be online: true and Postgres-backed, and the schema must have a running online
service.
The following example combines two online batch feature views into one feature group.
YAML (sources/feature_groups/USER_FRAUD_FG_DECL.yaml):
Python (sources/feature_groups/user_fraud_fg_decl.py):
The Python form accepts either the source feature view objects directly (as shown) or
FeatureViewRef(name=..., version=...) pairs that mirror the YAML shape. With
auto_prefix: true, each member’s output columns are prefixed with
<fv_name>_<fv_version>_ to avoid name collisions. Use the desc field (not
description) on a feature group, to match the imperative API.
Important
Feature groups have no in-place update. Any change to a feature group’s authored surface,
such as its description, auto_prefix, or member list, is a destructive recreate that
apply refuses without --destructive. A member feature view also can’t be dropped or
recreated while a feature group still references it.
For the concept, primary-key and join behavior, reading online, and training-set generation, see Feature groups.