Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
6cb9c8c
[FS-2621] Add the materialization set as a direct-engine bundle resource
Daniel114510 Oct 16, 2026
6d3beba
[FS-2621] Tighten the member-key and change-override doc comments
Daniel114510 Oct 16, 2026
f90f4dd
[FS-2621] Suppress the drift from destination fields the read never r…
Daniel114510 Oct 17, 2026
ea79075
[FS-2621] Add acceptance tests for the materialization set
Daniel114510 Oct 17, 2026
1246725
[FS-2621] Say what the change override does, and why the generated ru…
Daniel114510 Oct 17, 2026
f527f29
[FS-2621] Cover sawtooth and streaming, and correct one refusal again…
Daniel114510 Oct 17, 2026
50bb33e
[FS-2621] Record the two new cases and what a local cloud run needs
Daniel114510 Oct 17, 2026
13f9ffb
[FS-2621] Add a cloud-capable batch case, and normalize what only a c…
Daniel114510 Oct 17, 2026
7a7f205
[FS-2621] Record the batch case and the deployment-history blocker
Daniel114510 Oct 17, 2026
9bc9314
[FS-2621] Record what a workspace run proved, and the destination rul…
Daniel114510 Oct 19, 2026
837e1d8
[FS-2621] Resolve a set's destinations against bundle catalogs, and g…
Daniel114510 Oct 19, 2026
fd2e45b
[FS-2621] Follow the materialization set create into a long-running o…
Daniel114510 Oct 19, 2026
64f32e3
[FS-2621] Take the created set straight off the operation
Daniel114510 Oct 19, 2026
ad99f17
[FS-2621] Recreate a set when a member's pipeline schedule state changes
Daniel114510 Oct 19, 2026
ff2a209
[FS-2621] Fold the removal-scope case into membership and cover bind
Daniel114510 Oct 19, 2026
7c64278
[FS-2621] Run the membership and immutable cases against a workspace
Daniel114510 Oct 19, 2026
d46ed36
[FS-2621] Wait on the materialization set update and delete operations
Daniel114510 Oct 20, 2026
ea717a4
[FS-2621] Match the fake's refusal messages to the reworked set update
Daniel114510 Oct 20, 2026
32fe896
[FS-2621] Record that the cloud 500s track parallel load, not the fix…
Daniel114510 Oct 20, 2026
32a4fd0
[FS-2621] Restate a partly applied set change's failed members in the…
Daniel114510 Oct 20, 2026
31ce4a3
[FS-2621] Point the member key at the server class it duplicates
Daniel114510 Oct 21, 2026
8ee470c
[FS-2621] Pin the whole removal matrix, and the two refusals the fake…
Daniel114510 Oct 21, 2026
85ab9b0
[FS-2621] Record that the removal matrix passed against a workspace
Daniel114510 Oct 21, 2026
45caeae
[FS-2621] Read a settled-but-failed operation instead of its error de…
Daniel114510 Oct 22, 2026
a5710f6
[FS-2621] Correct the fake from what the live promotion tip returns
Daniel114510 Oct 22, 2026
d5b235b
[FS-2621] Name the outcome when an operation settles FAILED
Daniel114510 Oct 22, 2026
80ac9ba
[FS-2621] Declare one feature's materializations in a shorthand the C…
Daniel114510 Oct 23, 2026
6689576
[FS-2621] Record the shorthand case in the acceptance README
Daniel114510 Oct 23, 2026
dc11316
[FS-2621] Count an emptied member list as an update, not a recreate
Daniel114510 Oct 23, 2026
32bde05
[FS-2621] Pin the route the empty-set refusal names
Daniel114510 Oct 23, 2026
859898a
[FS-2621] Record every cloud case passing against a workspace
Daniel114510 Oct 23, 2026
17dd64c
[FS-2621] Report that a materialization set has no workspace URL
Daniel114510 Oct 23, 2026
b40016f
[FS-2621] Label the member key and omit an absent online store
Daniel114510 Oct 23, 2026
ee4cf0b
[FS-2621] Name the mutator for what it expands, and trim its comments
Daniel114510 Oct 23, 2026
d4b204a
[FS-2621] Scope the slice-pattern ignore comparison to materializatio…
Daniel114510 Oct 23, 2026
1f20d23
[FS-2621] Accept day and hour units in a feature's duration fields
Daniel114510 Oct 23, 2026
9bffa15
[FS-2621] Fold the canonical duration helper into its sole caller
Daniel114510 Oct 23, 2026
ae6ef4d
[FS-2621] Write the acceptance durations in mixed units
Daniel114510 Oct 23, 2026
495a363
[FS-2621] Walk a registry of duration fields instead of repeating the…
Daniel114510 Oct 23, 2026
61a6ca1
[FS-2621] Convert a window through one generic function instead of five
Daniel114510 Oct 24, 2026
789d7a9
[FS-2621] Name the duration helpers after what they convert
Daniel114510 Oct 24, 2026
989ea04
[FS-2621] Convert source lateness through the same generic function
Daniel114510 Oct 24, 2026
241322c
[FS-2621] Replace the reflective duration guard with a written checklist
Daniel114510 Oct 24, 2026
b4e589c
[FS-2621] Cover both shorthand fields and three duration forms
Daniel114510 Oct 24, 2026
74f5f4f
[FS-2621] Record that the expansion mutates typed state
Daniel114510 Oct 24, 2026
a6ad3b6
[FS-2621] Name the feature config wrappers after the API types they r…
Daniel114510 Oct 24, 2026
0f467a9
[FS-2621] Give each shorthand its own authoring type
Daniel114510 Oct 24, 2026
e0b3a78
[FS-2621] Refuse a set that asks for one member twice
Daniel114510 Oct 28, 2026
485951b
[FS-2621] Build against the released SDK and refresh the API spec
Daniel114510 Oct 28, 2026
22875e8
[FS-2621] Generate the artifacts describing the materialization set
Daniel114510 Oct 28, 2026
8e3bc5a
[FS-2621] Run the materialization set cases on the recorder-off leg only
Daniel114510 Oct 28, 2026
dd41c56
[FS-2621] Stop the shorthand golden pinning one workspace's online store
Daniel114510 Oct 28, 2026
c2959bb
Merge remote-tracking branch 'origin/main' into fs2910-matset-member-…
Daniel114510 Oct 28, 2026
4afefc2
[FS-2621] Keep uuid a direct dependency
Daniel114510 Oct 28, 2026
0b85584
[FS-2621] Add the two acceptance artifacts the resource was missing
Daniel114510 Oct 28, 2026
2b7a8b1
[FS-2621] Record the public API the resource adds, and uuid's license
Daniel114510 Oct 28, 2026
71632b8
[FS-2621] Satisfy the lint and generator rules the merge brought in
Daniel114510 Oct 28, 2026
73faac4
[FS-2621] Drop the recorder-on leg from the duration case
Daniel114510 Oct 28, 2026
2aef3f7
[FS-2621] Use the standard library's uuid for the idempotency token
Daniel114510 Oct 28, 2026
aa4be8e
[FS-2621] Run the Stream-backed cases locally only
Daniel114510 Oct 28, 2026
a570655
[FS-2621] Keep only the member-key check in the first release
Daniel114510 Oct 28, 2026
dfcde2d
[FS-2621] Take a duration in seconds only, as the API does
Daniel114510 Oct 28, 2026
bc0a47a
[FS-2621] Send the whole set on update
Daniel114510 Oct 28, 2026
557dbaf
[FS-2621] Edit the rendered config with the portable helper
Daniel114510 Oct 28, 2026
18e1a17
[FS-2621] Keep the batch case to batch features alone
Daniel114510 Oct 29, 2026
8c80848
[FS-2621] Send materialized_features as the update mask
Daniel114510 Oct 29, 2026
27b8ac8
[FS-2621] Create each cloud case's schema, and materialize offline only
Daniel114510 Oct 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
features:
foo:
full_name: main.matset_inv_$UNIQUE_NAME.test_feature
source:
delta_table_source:
full_name: main.matset_inv_$UNIQUE_NAME.source_table
function:
aggregation_function:
count_function:
input: value
time_window:
sliding:
window_duration: 604800s
slide_duration: 86400s
entities:
- name: id
timeseries_column:
name: timestamp

materialization_sets:
foo:
materialized_features:
- feature_name: ${resources.features.foo.full_name}
offline_store_config:
catalog_name: main
schema_name: matset_inv_$UNIQUE_NAME
table_name_prefix: offline
cron_schedule_trigger:
mode: MANUAL
cron_expression: "0 0 * * * ?"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

# The offline materialization leaves its own tables behind, so the schema is dropped with CASCADE.
echo "Cleaning up temporary source table"
$CLI tables delete main.matset_inv_$UNIQUE_NAME.source_table || true
$CLI schemas delete main.matset_inv_$UNIQUE_NAME --force || true
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

# The feature's delta_table_source must already exist, and the invariant harness provisions no
# tables of its own.
echo "Creating temporary source table: main.matset_inv_$UNIQUE_NAME.source_table"

$CLI schemas create matset_inv_$UNIQUE_NAME main -o json | jq '{full_name}'

# MSYS_NO_PATHCONV=1 prevents Git Bash on Windows from converting /api/... to a filesystem path.
MSYS_NO_PATHCONV=1 $CLI api post "/api/2.0/sql/statements/" --json "{
\"warehouse_id\": \"$TEST_DEFAULT_WAREHOUSE_ID\",
\"statement\": \"CREATE TABLE main.matset_inv_$UNIQUE_NAME.source_table (id INT, value STRING, timestamp TIMESTAMP) USING DELTA\",
\"wait_timeout\": \"45s\"
}" > /dev/null
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
bundle:
name: my_project

sync: {paths: []} # don't need to copy files

python:
resources:
- "resources:load_resources"
mutators:
- "mutators:update_materialization_set"

resources:
materialization_sets:
my_materialization_set_1:
materialized_features:
- feature_name: main.default.my_feature_1
offline_store_config:
catalog_name: main
schema_name: default
table_name_prefix: my_feature_1_off
cron_schedule_trigger:
mode: DERIVED
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from dataclasses import replace

from databricks.bundles.core import materialization_set_mutator
from databricks.bundles.materialization_sets import MaterializationSet


@materialization_set_mutator
def update_materialization_set(
materialization_set: MaterializationSet,
) -> MaterializationSet:
# A set has no string field of its own, so the member's feature name is what a mutator can
# observably change.
members = list(materialization_set.materialized_features)
first = members[0]
assert isinstance(first.feature_name, str)

return replace(
materialization_set,
materialized_features=[
replace(first, feature_name=f"{first.feature_name}_updated"),
*members[1:],
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Cloud = false
EnvMatrix.DMS = ["", "true"]
EnvMatrix.PYDAB_VERSION = ["current"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@

>>> uv run [UV_ARGS] -q [CLI] bundle validate --output json
{
"experimental": {
"python": {
"mutators": [
"mutators:update_materialization_set"
],
"resources": [
"resources:load_resources"
]
}
},
"resources": {
"materialization_sets": {
"my_materialization_set_1": {
"materialized_features": [
{
"cron_schedule_trigger": {
"mode": "DERIVED"
},
"feature_name": "main.default.my_feature_1_updated",
"offline_store_config": {
"catalog_name": "main",
"schema_name": "default",
"table_name_prefix": "my_feature_1_off"
}
}
]
},
"my_materialization_set_2": {
"materialized_features": [
{
"cron_schedule_trigger": {
"mode": "DERIVED"
},
"feature_name": "main.default.my_feature_2_updated",
"offline_store_config": {
"catalog_name": "main",
"schema_name": "default",
"table_name_prefix": "my_feature_2_off"
}
}
]
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from databricks.bundles.core import Resources


def load_resources() -> Resources:
resources = Resources()

resources.add_materialization_set(
"my_materialization_set_2",
{
"materialized_features": [
{
"feature_name": "main.default.my_feature_2",
"offline_store_config": {
"catalog_name": "main",
"schema_name": "default",
"table_name_prefix": "my_feature_2_off",
},
"cron_schedule_trigger": {"mode": "DERIVED"},
},
],
},
)

return resources
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

trace uv run $UV_ARGS -q $CLI bundle validate --output json | \
jq "pick(.experimental.python, .resources)"

rm -fr .databricks __pycache__
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Cloud = false # tests don't interact with APIs

# materialization sets are only supported in the current version of the wheel
EnvMatrix.PYDAB_VERSION = ["current"]
58 changes: 58 additions & 0 deletions acceptance/bundle/refschema/output/materialization_sets.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
resources.materialization_sets.*.id string INPUT
resources.materialization_sets.*.lifecycle resources.Lifecycle INPUT
resources.materialization_sets.*.lifecycle.depends_on []resources.DependsOn INPUT
resources.materialization_sets.*.lifecycle.depends_on[*] resources.DependsOn INPUT
resources.materialization_sets.*.lifecycle.depends_on[*].resource string INPUT
resources.materialization_sets.*.lifecycle.prevent_destroy bool INPUT
resources.materialization_sets.*.materialization_set_id string ALL
resources.materialization_sets.*.materialized_features []ml.MaterializedFeature ALL
resources.materialization_sets.*.materialized_features[*] ml.MaterializedFeature ALL
resources.materialization_sets.*.materialized_features[*].budget_policy_id string ALL
resources.materialization_sets.*.materialized_features[*].cron_schedule string ALL
resources.materialization_sets.*.materialized_features[*].cron_schedule_trigger *ml.CronSchedule ALL
resources.materialization_sets.*.materialized_features[*].cron_schedule_trigger.cron_expression string ALL
resources.materialization_sets.*.materialized_features[*].cron_schedule_trigger.mode ml.CronScheduleMode ALL
resources.materialization_sets.*.materialized_features[*].cron_schedule_trigger.timezone_id string ALL
resources.materialization_sets.*.materialized_features[*].feature_name string ALL
resources.materialization_sets.*.materialized_features[*].is_online bool ALL
resources.materialization_sets.*.materialized_features[*].job_id int64 ALL
resources.materialization_sets.*.materialized_features[*].last_materialization_time string ALL
resources.materialization_sets.*.materialized_features[*].latest_backfill_operation string ALL
resources.materialization_sets.*.materialized_features[*].materialization_set_id string ALL
resources.materialization_sets.*.materialized_features[*].materialized_feature_id string ALL
resources.materialization_sets.*.materialized_features[*].notifications *ml.MaterializationNotifications ALL
resources.materialization_sets.*.materialized_features[*].notifications.on_failure *ml.MaterializationFailureNotification ALL
resources.materialization_sets.*.materialized_features[*].notifications.on_failure.destination_ids []string ALL
resources.materialization_sets.*.materialized_features[*].notifications.on_failure.destination_ids[*] string ALL
resources.materialization_sets.*.materialized_features[*].notifications.on_failure.email_addresses []string ALL
resources.materialization_sets.*.materialized_features[*].notifications.on_failure.email_addresses[*] string ALL
resources.materialization_sets.*.materialized_features[*].notifications.on_failure.final_attempt_only bool ALL
resources.materialization_sets.*.materialized_features[*].notifications.on_success *ml.MaterializationSuccessNotification ALL
resources.materialization_sets.*.materialized_features[*].notifications.on_success.destination_ids []string ALL
resources.materialization_sets.*.materialized_features[*].notifications.on_success.destination_ids[*] string ALL
resources.materialization_sets.*.materialized_features[*].notifications.on_success.email_addresses []string ALL
resources.materialization_sets.*.materialized_features[*].notifications.on_success.email_addresses[*] string ALL
resources.materialization_sets.*.materialized_features[*].offline_store_config *ml.OfflineStoreConfig ALL
resources.materialization_sets.*.materialized_features[*].offline_store_config.catalog_name string ALL
resources.materialization_sets.*.materialized_features[*].offline_store_config.schema_name string ALL
resources.materialization_sets.*.materialized_features[*].offline_store_config.table_name_prefix string ALL
resources.materialization_sets.*.materialized_features[*].online_store_config *ml.OnlineStoreConfig ALL
resources.materialization_sets.*.materialized_features[*].online_store_config.catalog_name string ALL
resources.materialization_sets.*.materialized_features[*].online_store_config.online_store_name string ALL
resources.materialization_sets.*.materialized_features[*].online_store_config.schema_name string ALL
resources.materialization_sets.*.materialized_features[*].online_store_config.table_name_prefix string ALL
resources.materialization_sets.*.materialized_features[*].pipeline_id string ALL
resources.materialization_sets.*.materialized_features[*].pipeline_schedule_state ml.MaterializedFeaturePipelineScheduleState ALL
resources.materialization_sets.*.materialized_features[*].streaming_mode *ml.StreamingMode ALL
resources.materialization_sets.*.materialized_features[*].streaming_mode.freshness_target string ALL
resources.materialization_sets.*.materialized_features[*].streaming_mode.mode ml.StreamingModeStreamingModeType ALL
resources.materialization_sets.*.materialized_features[*].streaming_mode.shuffle_partitions int ALL
resources.materialization_sets.*.materialized_features[*].table_name string ALL
resources.materialization_sets.*.materialized_features[*].table_trigger *ml.TableTrigger ALL
resources.materialization_sets.*.materialized_features[*].table_trigger.condition ml.TableTriggerTableTriggerCondition ALL
resources.materialization_sets.*.materialized_features[*].table_trigger.min_time_between_triggers *duration.Duration ALL
resources.materialization_sets.*.materialized_features[*].table_trigger.wait_after_last_change *duration.Duration ALL
resources.materialization_sets.*.materialized_features[*].tags map[string]string ALL
resources.materialization_sets.*.materialized_features[*].tags.* string ALL
resources.materialization_sets.*.modified_status string INPUT
resources.materialization_sets.*.url string INPUT
Loading
Loading