Skip to content

[Fix] Fix filling of missing attributes in databricks_quality_monitor #4519

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Feb 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion NEXT_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

* Mark `default_catalog_name` attribute in `databricks_metastore_assignment` as deprecated ([#4522](https://github.com/databricks/terraform-provider-databricks/pull/4522))
* Delete `databricks_sql_endpoint` that failed to start ([#4520](https://github.com/databricks/terraform-provider-databricks/pull/4520))
* Fix filling of missing attributes in `databricks_quality_monitor` ([#4519](https://github.com/databricks/terraform-provider-databricks/pull/4519)).

### Documentation

Expand All @@ -23,4 +24,4 @@

### Internal Changes

* Bump golang version to 1.24.0 ([#4508](https://github.com/databricks/terraform-provider-databricks/pull/4508)).
* Bump golang version to 1.24.0 ([#4508](https://github.com/databricks/terraform-provider-databricks/pull/4508)).
3 changes: 3 additions & 0 deletions catalog/quality_monitor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ resource "databricks_sql_table" "myInferenceTable" {
name = "bar{var.STICKY_RANDOM}_inference"
table_type = "MANAGED"
data_source_format = "DELTA"
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"

column {
name = "model_id"
Expand Down Expand Up @@ -79,6 +80,7 @@ func TestUcAccQualityMonitor(t *testing.T) {
name = "bar{var.STICKY_RANDOM}_timeseries"
table_type = "MANAGED"
data_source_format = "DELTA"
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"

column {
name = "timestamp"
Expand Down Expand Up @@ -106,6 +108,7 @@ func TestUcAccQualityMonitor(t *testing.T) {
name = "bar{var.STICKY_RANDOM}_snapshot"
table_type = "MANAGED"
data_source_format = "DELTA"
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"

column {
name = "timestamp"
Expand Down
13 changes: 12 additions & 1 deletion catalog/resource_quality_monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,18 @@ func ResourceQualityMonitor() common.Resource {
return err

}
return common.StructToData(endpoint, monitorSchema, d)
oldWarehouseId := d.Get("warehouse_id").(string)
oldSkipBuiltinDashboard := d.Get("skip_builtin_dashboard").(bool)

err = common.StructToData(endpoint, monitorSchema, d)
if err != nil {
return err
}
// we need this because Get API doesn't return that information
d.Set("warehouse_id", oldWarehouseId)
d.Set("skip_builtin_dashboard", oldSkipBuiltinDashboard)

return nil
},
Update: func(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient) error {
w, err := c.WorkspaceClient()
Expand Down
15 changes: 11 additions & 4 deletions catalog/resource_quality_monitor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ func TestQualityMonitorCreateTimeseries(t *testing.T) {
MockWorkspaceClientFunc: func(w *mocks.MockWorkspaceClient) {
e := w.GetMockQualityMonitorsAPI().EXPECT()
e.Create(mock.Anything, catalog.CreateMonitor{
TableName: "test_table",
OutputSchemaName: "output.schema",
AssetsDir: "sample.dir",
TableName: "test_table",
OutputSchemaName: "output.schema",
AssetsDir: "sample.dir",
WarehouseId: "1234",
SkipBuiltinDashboard: true,
TimeSeries: &catalog.MonitorTimeSeries{
Granularities: []string{"1 day"},
TimestampCol: "timestamp",
Expand All @@ -45,13 +47,18 @@ func TestQualityMonitorCreateTimeseries(t *testing.T) {
table_name = "test_table",
assets_dir = "sample.dir",
output_schema_name = "output.schema",
warehouse_id = "1234",
skip_builtin_dashboard = true,
time_series = {
granularities = ["1 day"],
timestamp_col = "timestamp"
}
`,
Create: true,
}.ApplyNoError(t)
}.ApplyAndExpectData(t, map[string]any{
"warehouse_id": "1234",
"skip_builtin_dashboard": true,
})
}

func TestQualityMonitorCreateInference(t *testing.T) {
Expand Down
7 changes: 4 additions & 3 deletions docs/resources/quality_monitor.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ subcategory: "Unity Catalog"

This resource allows you to manage [Lakehouse Monitors](https://docs.databricks.com/en/lakehouse-monitoring/index.html) in Databricks.

A `databricks_quality_monitor` is attached to a [databricks_sql_table](sql_table.md) and can be of type timeseries, snapshot or inference.
A `databricks_quality_monitor` is attached to a [databricks_sql_table](sql_table.md) and can be of type timeseries, snapshot or inference.

## Plugin Framework Migration

The quality monitor resource has been migrated from sdkv2 to plugin framework。 If you encounter any problem with this resource and suspect it is due to the migration, you can fallback to sdkv2 by setting the environment variable in the following way `export USE_SDK_V2_RESOURCES="databricks_quality_monitor"`.

## Example Usage
Expand Down Expand Up @@ -114,9 +115,9 @@ table.
* `schedule` - The schedule for automatically updating and refreshing metric tables. This block consists of following fields:
* `quartz_cron_expression` - string expression that determines when to run the monitor. See [Quartz documentation](https://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html) for examples.
* `timezone_id` - string with timezone id (e.g., `PST`) in which to evaluate the Quartz expression.
* `skip_builtin_dashboard` - Whether to skip creating a default dashboard summarizing data quality metrics.
* `skip_builtin_dashboard` - Whether to skip creating a default dashboard summarizing data quality metrics. (Can't be updated after creation).
* `slicing_exprs` - List of column expressions to slice data with for targeted analysis. The data is grouped by each expression independently, resulting in a separate slice for each predicate and its complements. For high-cardinality columns, only the top 100 unique values by frequency will generate slices.
* `warehouse_id` - Optional argument to specify the warehouse for dashboard creation. If not specified, the first running warehouse will be used.
* `warehouse_id` - Optional argument to specify the warehouse for dashboard creation. If not specified, the first running warehouse will be used. (Can't be updated after creation)

## Attribute Reference

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ func (r *QualityMonitorResource) Create(ctx context.Context, req resource.Create

// Set the ID to the table name
newMonitorInfoTfSDK.ID = newMonitorInfoTfSDK.TableName
// We need it to fill additional fields as they are not returned by the API
newMonitorInfoTfSDK.WarehouseId = monitorInfoTfSDK.WarehouseId
newMonitorInfoTfSDK.SkipBuiltinDashboard = monitorInfoTfSDK.SkipBuiltinDashboard

resp.Diagnostics.Append(resp.State.Set(ctx, newMonitorInfoTfSDK)...)
}
Expand Down Expand Up @@ -179,6 +182,20 @@ func (r *QualityMonitorResource) Read(ctx context.Context, req resource.ReadRequ
}

monitorInfoTfSDK.ID = monitorInfoTfSDK.TableName
// We need it to fill additional fields as they are not returned by the API
var origWarehouseId types.String
var origSkipBuiltinDashboard types.Bool
resp.Diagnostics.Append(req.State.GetAttribute(ctx, path.Root("warehouse_id"), &origWarehouseId)...)
resp.Diagnostics.Append(req.State.GetAttribute(ctx, path.Root("skip_builtin_dashboard"), &origSkipBuiltinDashboard)...)
if resp.Diagnostics.HasError() {
return
}
if origWarehouseId.ValueString() != "" {
monitorInfoTfSDK.WarehouseId = origWarehouseId
}
if origSkipBuiltinDashboard.ValueBool() {
monitorInfoTfSDK.SkipBuiltinDashboard = origSkipBuiltinDashboard
}

resp.Diagnostics.Append(resp.State.Set(ctx, monitorInfoTfSDK)...)
}
Expand Down Expand Up @@ -225,6 +242,12 @@ func (r *QualityMonitorResource) Update(ctx context.Context, req resource.Update
if resp.Diagnostics.HasError() {
return
}
// We need it to fill additional fields as they are not returned by the API
resp.Diagnostics.Append(req.State.GetAttribute(ctx, path.Root("warehouse_id"), &newMonitorInfoTfSDK.WarehouseId)...)
resp.Diagnostics.Append(req.State.GetAttribute(ctx, path.Root("skip_builtin_dashboard"), &newMonitorInfoTfSDK.SkipBuiltinDashboard)...)
if resp.Diagnostics.HasError() {
return
}

resp.Diagnostics.Append(resp.State.Set(ctx, newMonitorInfoTfSDK)...)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ resource "databricks_sql_table" "myInferenceTable" {
name = "bar{var.STICKY_RANDOM}_inference"
table_type = "MANAGED"
data_source_format = "DELTA"
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"

column {
name = "model_id"
Expand Down Expand Up @@ -63,6 +64,7 @@ func TestUcAccQualityMonitor(t *testing.T) {
table_name = databricks_sql_table.myInferenceTable.id
assets_dir = "/Shared/provider-test/databricks_quality_monitoring/${databricks_sql_table.myInferenceTable.name}"
output_schema_name = databricks_schema.things.id
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
inference_log {
granularities = ["1 day"]
timestamp_col = "timestamp"
Expand All @@ -78,6 +80,7 @@ func TestUcAccQualityMonitor(t *testing.T) {
name = "bar{var.STICKY_RANDOM}_timeseries"
table_type = "MANAGED"
data_source_format = "DELTA"
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"

column {
name = "timestamp"
Expand All @@ -89,6 +92,7 @@ func TestUcAccQualityMonitor(t *testing.T) {
table_name = databricks_sql_table.myTimeseries.id
assets_dir = "/Shared/provider-test/databricks_quality_monitoring/${databricks_sql_table.myTimeseries.name}"
output_schema_name = databricks_schema.things.id
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
time_series {
granularities = ["1 day"]
timestamp_col = "timestamp"
Expand All @@ -101,6 +105,7 @@ func TestUcAccQualityMonitor(t *testing.T) {
name = "bar{var.STICKY_RANDOM}_snapshot"
table_type = "MANAGED"
data_source_format = "DELTA"
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"

column {
name = "timestamp"
Expand All @@ -112,6 +117,7 @@ func TestUcAccQualityMonitor(t *testing.T) {
table_name = databricks_sql_table.mySnapshot.id
assets_dir = "/Shared/provider-test/databricks_quality_monitoring/${databricks_sql_table.myTimeseries.name}"
output_schema_name = databricks_schema.things.id
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
snapshot {
}
}
Expand All @@ -129,6 +135,7 @@ func TestUcAccUpdateQualityMonitor(t *testing.T) {
table_name = databricks_sql_table.myInferenceTable.id
assets_dir = "/Shared/provider-test/databricks_quality_monitoring/${databricks_sql_table.myInferenceTable.name}"
output_schema_name = databricks_schema.things.id
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
inference_log {
granularities = ["1 day"]
timestamp_col = "timestamp"
Expand All @@ -144,6 +151,7 @@ func TestUcAccUpdateQualityMonitor(t *testing.T) {
table_name = databricks_sql_table.myInferenceTable.id
assets_dir = "/Shared/provider-test/databricks_quality_monitoring/${databricks_sql_table.myInferenceTable.name}"
output_schema_name = databricks_schema.things.id
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
inference_log {
granularities = ["1 hour"]
timestamp_col = "timestamp"
Expand Down Expand Up @@ -228,6 +236,7 @@ func TestUcAccUpdateQualityMonitorTransitionFromPluginFw(t *testing.T) {
table_name = databricks_sql_table.myInferenceTable.id
assets_dir = "/Shared/provider-test/databricks_quality_monitoring/${databricks_sql_table.myInferenceTable.name}"
output_schema_name = databricks_schema.things.id
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
inference_log {
granularities = ["1 hour"]
timestamp_col = "timestamp"
Expand Down
Loading