Make `TableName` field part of quality monitor schema (#1903)

## Changes

This field was special-cased in #1307 because it's not part of the JSON
payload in the SDK struct.

This approach, while pragmatic, meant it didn't show up in the JSON
schema. While debugging an issue with quality monitors in #1900, I
couldn't figure out why I was getting schema errors on this field, or
how it was passed through to the TF representation. This commit removes
the special case and makes it behave like everything else.

## Tests

* Unit tests pass.
* Confirmed that the updated schema failed validation before this
change.
This commit is contained in:
Pieter Noordhuis 2024-11-14 18:39:38 +01:00 committed by GitHub
parent 1508d65c4c
commit 1db384018c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 27 additions and 27 deletions

View File

@ -65,9 +65,8 @@ func TestInitializeURLs(t *testing.T) {
}, },
QualityMonitors: map[string]*resources.QualityMonitor{ QualityMonitors: map[string]*resources.QualityMonitor{
"qualityMonitor1": { "qualityMonitor1": {
CreateMonitor: &catalog.CreateMonitor{
TableName: "catalog.schema.qualityMonitor1", TableName: "catalog.schema.qualityMonitor1",
}, CreateMonitor: &catalog.CreateMonitor{},
}, },
}, },
Schemas: map[string]*resources.Schema{ Schemas: map[string]*resources.Schema{

View File

@ -102,16 +102,23 @@ func mockBundle(mode config.Mode) *bundle.Bundle {
"registeredmodel1": {CreateRegisteredModelRequest: &catalog.CreateRegisteredModelRequest{Name: "registeredmodel1"}}, "registeredmodel1": {CreateRegisteredModelRequest: &catalog.CreateRegisteredModelRequest{Name: "registeredmodel1"}},
}, },
QualityMonitors: map[string]*resources.QualityMonitor{ QualityMonitors: map[string]*resources.QualityMonitor{
"qualityMonitor1": {CreateMonitor: &catalog.CreateMonitor{TableName: "qualityMonitor1"}}, "qualityMonitor1": {
"qualityMonitor2": { TableName: "qualityMonitor1",
CreateMonitor: &catalog.CreateMonitor{ CreateMonitor: &catalog.CreateMonitor{
OutputSchemaName: "catalog.schema",
},
},
"qualityMonitor2": {
TableName: "qualityMonitor2", TableName: "qualityMonitor2",
CreateMonitor: &catalog.CreateMonitor{
OutputSchemaName: "catalog.schema",
Schedule: &catalog.MonitorCronSchedule{}, Schedule: &catalog.MonitorCronSchedule{},
}, },
}, },
"qualityMonitor3": { "qualityMonitor3": {
CreateMonitor: &catalog.CreateMonitor{
TableName: "qualityMonitor3", TableName: "qualityMonitor3",
CreateMonitor: &catalog.CreateMonitor{
OutputSchemaName: "catalog.schema",
Schedule: &catalog.MonitorCronSchedule{ Schedule: &catalog.MonitorCronSchedule{
PauseStatus: catalog.MonitorCronSchedulePauseStatusUnpaused, PauseStatus: catalog.MonitorCronSchedulePauseStatusUnpaused,
}, },

View File

@ -13,17 +13,15 @@ import (
) )
type QualityMonitor struct { type QualityMonitor struct {
// Represents the Input Arguments for Terraform and will get
// converted to a HCL representation for CRUD
*catalog.CreateMonitor
// This represents the id which is the full name of the monitor
// (catalog_name.schema_name.table_name) that can be used
// as a reference in other resources. This value is returned by terraform.
ID string `json:"id,omitempty" bundle:"readonly"` ID string `json:"id,omitempty" bundle:"readonly"`
ModifiedStatus ModifiedStatus `json:"modified_status,omitempty" bundle:"internal"` ModifiedStatus ModifiedStatus `json:"modified_status,omitempty" bundle:"internal"`
URL string `json:"url,omitempty" bundle:"internal"` URL string `json:"url,omitempty" bundle:"internal"`
// The table name is a required field but not included as a JSON field in [catalog.CreateMonitor].
TableName string `json:"table_name"`
// This struct defines the creation payload for a monitor.
*catalog.CreateMonitor
} }
func (s *QualityMonitor) UnmarshalJSON(b []byte) error { func (s *QualityMonitor) UnmarshalJSON(b []byte) error {

View File

@ -15,8 +15,8 @@ import (
func TestConvertQualityMonitor(t *testing.T) { func TestConvertQualityMonitor(t *testing.T) {
var src = resources.QualityMonitor{ var src = resources.QualityMonitor{
CreateMonitor: &catalog.CreateMonitor{
TableName: "test_table_name", TableName: "test_table_name",
CreateMonitor: &catalog.CreateMonitor{
AssetsDir: "assets_dir", AssetsDir: "assets_dir",
OutputSchemaName: "output_schema_name", OutputSchemaName: "output_schema_name",
InferenceLog: &catalog.MonitorInferenceLog{ InferenceLog: &catalog.MonitorInferenceLog{

View File

@ -4,6 +4,7 @@ bundle:
resources: resources:
quality_monitors: quality_monitors:
myqualitymonitor: myqualitymonitor:
table_name: catalog.schema.quality_monitor
inference_log: inference_log:
granularities: granularities:
- a - a

View File

@ -684,6 +684,9 @@
"description": "Configuration for monitoring snapshot tables.", "description": "Configuration for monitoring snapshot tables.",
"$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/catalog.MonitorSnapshot" "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/catalog.MonitorSnapshot"
}, },
"table_name": {
"$ref": "#/$defs/string"
},
"time_series": { "time_series": {
"description": "Configuration for monitoring time series tables.", "description": "Configuration for monitoring time series tables.",
"$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/catalog.MonitorTimeSeries" "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/catalog.MonitorTimeSeries"
@ -695,6 +698,7 @@
}, },
"additionalProperties": false, "additionalProperties": false,
"required": [ "required": [
"table_name",
"assets_dir", "assets_dir",
"output_schema_name" "output_schema_name"
] ]

View File

@ -6,7 +6,6 @@ import (
"sync" "sync"
"github.com/databricks/cli/libs/dyn" "github.com/databricks/cli/libs/dyn"
"github.com/databricks/cli/libs/textutil"
) )
// structInfo holds the type information we need to efficiently // structInfo holds the type information we need to efficiently
@ -85,14 +84,6 @@ func buildStructInfo(typ reflect.Type) structInfo {
} }
name, _, _ := strings.Cut(sf.Tag.Get("json"), ",") name, _, _ := strings.Cut(sf.Tag.Get("json"), ",")
if typ.Name() == "QualityMonitor" && name == "-" {
urlName, _, _ := strings.Cut(sf.Tag.Get("url"), ",")
if urlName == "" || urlName == "-" {
name = textutil.CamelToSnakeCase(sf.Name)
} else {
name = urlName
}
}
if name == "" || name == "-" { if name == "" || name == "-" {
continue continue
} }