# Code generated from OpenAPI specs by Databricks SDK Generator. DO NOT EDIT. from __future__ import annotations import logging import random import time import uuid from dataclasses import dataclass from datetime import timedelta from enum import Enum from typing import Any, Callable, Dict, Iterator, List, Optional from databricks.sdk.client_types import HostType from databricks.sdk.service._internal import (Wait, _enum, _from_dict, _repeated_dict) _LOG = logging.getLogger("databricks.sdk") # all definitions in this file are in alphabetical order @dataclass class CustomTag: key: Optional[str] = None """The key of the custom tag.""" value: Optional[str] = None """The value of the custom tag.""" def as_dict(self) -> dict: """Serializes the CustomTag into a dictionary suitable for use as a JSON request body.""" body = {} if self.key is not None: body["key"] = self.key if self.value is not None: body["value"] = self.value return body def as_shallow_dict(self) -> dict: """Serializes the CustomTag into a shallow dictionary of its immediate attributes.""" body = {} if self.key is not None: body["key"] = self.key if self.value is not None: body["value"] = self.value return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> CustomTag: """Deserializes the CustomTag from a dictionary.""" return cls(key=d.get("key", None), value=d.get("value", None)) @dataclass class DatabaseCatalog: name: str """The name of the catalog in UC.""" database_instance_name: str """The name of the DatabaseInstance housing the database.""" database_name: str """The name of the database (in a instance) associated with the catalog.""" create_database_if_not_exists: Optional[bool] = None uid: Optional[str] = None def as_dict(self) -> dict: """Serializes the DatabaseCatalog into a dictionary suitable for use as a JSON request body.""" body = {} if self.create_database_if_not_exists is not None: body["create_database_if_not_exists"] = self.create_database_if_not_exists if self.database_instance_name is not None: body["database_instance_name"] = self.database_instance_name if self.database_name is not None: body["database_name"] = self.database_name if self.name is not None: body["name"] = self.name if self.uid is not None: body["uid"] = self.uid return body def as_shallow_dict(self) -> dict: """Serializes the DatabaseCatalog into a shallow dictionary of its immediate attributes.""" body = {} if self.create_database_if_not_exists is not None: body["create_database_if_not_exists"] = self.create_database_if_not_exists if self.database_instance_name is not None: body["database_instance_name"] = self.database_instance_name if self.database_name is not None: body["database_name"] = self.database_name if self.name is not None: body["name"] = self.name if self.uid is not None: body["uid"] = self.uid return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> DatabaseCatalog: """Deserializes the DatabaseCatalog from a dictionary.""" return cls( create_database_if_not_exists=d.get("create_database_if_not_exists", None), database_instance_name=d.get("database_instance_name", None), database_name=d.get("database_name", None), name=d.get("name", None), uid=d.get("uid", None), ) @dataclass class DatabaseCredential: expiration_time: Optional[str] = None token: Optional[str] = None def as_dict(self) -> dict: """Serializes the DatabaseCredential into a dictionary suitable for use as a JSON request body.""" body = {} if self.expiration_time is not None: body["expiration_time"] = self.expiration_time if self.token is not None: body["token"] = self.token return body def as_shallow_dict(self) -> dict: """Serializes the DatabaseCredential into a shallow dictionary of its immediate attributes.""" body = {} if self.expiration_time is not None: body["expiration_time"] = self.expiration_time if self.token is not None: body["token"] = self.token return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> DatabaseCredential: """Deserializes the DatabaseCredential from a dictionary.""" return cls(expiration_time=d.get("expiration_time", None), token=d.get("token", None)) @dataclass class DatabaseInstance: """A DatabaseInstance represents a logical Postgres instance, comprised of both compute and storage.""" name: str """The name of the instance. This is the unique identifier for the instance.""" capacity: Optional[str] = None """The sku of the instance. Valid values are "CU_1", "CU_2", "CU_4", "CU_8".""" child_instance_refs: Optional[List[DatabaseInstanceRef]] = None """The refs of the child instances. This is only available if the instance is parent instance.""" creation_time: Optional[str] = None """The timestamp when the instance was created.""" creator: Optional[str] = None """The email of the creator of the instance.""" custom_tags: Optional[List[CustomTag]] = None """Custom tags associated with the instance. This field is only included on create and update responses.""" effective_capacity: Optional[str] = None """Deprecated. The sku of the instance; this field will always match the value of capacity. This is an output only field that contains the value computed from the input field combined with server side defaults. Use the field without the effective_ prefix to set the value.""" effective_custom_tags: Optional[List[CustomTag]] = None """The recorded custom tags associated with the instance. This is an output only field that contains the value computed from the input field combined with server side defaults. Use the field without the effective_ prefix to set the value.""" effective_enable_pg_native_login: Optional[bool] = None """Whether the instance has PG native password login enabled. This is an output only field that contains the value computed from the input field combined with server side defaults. Use the field without the effective_ prefix to set the value.""" effective_enable_readable_secondaries: Optional[bool] = None """Whether secondaries serving read-only traffic are enabled. Defaults to false. This is an output only field that contains the value computed from the input field combined with server side defaults. Use the field without the effective_ prefix to set the value.""" effective_node_count: Optional[int] = None """The number of nodes in the instance, composed of 1 primary and 0 or more secondaries. Defaults to 1 primary and 0 secondaries. This is an output only field that contains the value computed from the input field combined with server side defaults. Use the field without the effective_ prefix to set the value.""" effective_retention_window_in_days: Optional[int] = None """The retention window for the instance. This is the time window in days for which the historical data is retained. This is an output only field that contains the value computed from the input field combined with server side defaults. Use the field without the effective_ prefix to set the value.""" effective_stopped: Optional[bool] = None """Whether the instance is stopped. This is an output only field that contains the value computed from the input field combined with server side defaults. Use the field without the effective_ prefix to set the value.""" effective_usage_policy_id: Optional[str] = None """The policy that is applied to the instance. This is an output only field that contains the value computed from the input field combined with server side defaults. Use the field without the effective_ prefix to set the value.""" enable_pg_native_login: Optional[bool] = None """Whether to enable PG native password login on the instance. Defaults to false.""" enable_readable_secondaries: Optional[bool] = None """Whether to enable secondaries to serve read-only traffic. Defaults to false.""" node_count: Optional[int] = None """The number of nodes in the instance, composed of 1 primary and 0 or more secondaries. Defaults to 1 primary and 0 secondaries. This field is input only, see effective_node_count for the output.""" parent_instance_ref: Optional[DatabaseInstanceRef] = None """The ref of the parent instance. This is only available if the instance is child instance. Input: For specifying the parent instance to create a child instance. Optional. Output: Only populated if provided as input to create a child instance.""" pg_version: Optional[str] = None """The version of Postgres running on the instance.""" read_only_dns: Optional[str] = None """The DNS endpoint to connect to the instance for read only access. This is only available if enable_readable_secondaries is true.""" read_write_dns: Optional[str] = None """The DNS endpoint to connect to the instance for read+write access.""" retention_window_in_days: Optional[int] = None """The retention window for the instance. This is the time window in days for which the historical data is retained. The default value is 7 days. Valid values are 2 to 35 days.""" state: Optional[DatabaseInstanceState] = None """The current state of the instance.""" stopped: Optional[bool] = None """Whether to stop the instance. An input only param, see effective_stopped for the output.""" uid: Optional[str] = None """An immutable UUID identifier for the instance.""" usage_policy_id: Optional[str] = None """The desired usage policy to associate with the instance.""" def as_dict(self) -> dict: """Serializes the DatabaseInstance into a dictionary suitable for use as a JSON request body.""" body = {} if self.capacity is not None: body["capacity"] = self.capacity if self.child_instance_refs: body["child_instance_refs"] = [v.as_dict() for v in self.child_instance_refs] if self.creation_time is not None: body["creation_time"] = self.creation_time if self.creator is not None: body["creator"] = self.creator if self.custom_tags: body["custom_tags"] = [v.as_dict() for v in self.custom_tags] if self.effective_capacity is not None: body["effective_capacity"] = self.effective_capacity if self.effective_custom_tags: body["effective_custom_tags"] = [v.as_dict() for v in self.effective_custom_tags] if self.effective_enable_pg_native_login is not None: body["effective_enable_pg_native_login"] = self.effective_enable_pg_native_login if self.effective_enable_readable_secondaries is not None: body["effective_enable_readable_secondaries"] = self.effective_enable_readable_secondaries if self.effective_node_count is not None: body["effective_node_count"] = self.effective_node_count if self.effective_retention_window_in_days is not None: body["effective_retention_window_in_days"] = self.effective_retention_window_in_days if self.effective_stopped is not None: body["effective_stopped"] = self.effective_stopped if self.effective_usage_policy_id is not None: body["effective_usage_policy_id"] = self.effective_usage_policy_id if self.enable_pg_native_login is not None: body["enable_pg_native_login"] = self.enable_pg_native_login if self.enable_readable_secondaries is not None: body["enable_readable_secondaries"] = self.enable_readable_secondaries if self.name is not None: body["name"] = self.name if self.node_count is not None: body["node_count"] = self.node_count if self.parent_instance_ref: body["parent_instance_ref"] = self.parent_instance_ref.as_dict() if self.pg_version is not None: body["pg_version"] = self.pg_version if self.read_only_dns is not None: body["read_only_dns"] = self.read_only_dns if self.read_write_dns is not None: body["read_write_dns"] = self.read_write_dns if self.retention_window_in_days is not None: body["retention_window_in_days"] = self.retention_window_in_days if self.state is not None: body["state"] = self.state.value if self.stopped is not None: body["stopped"] = self.stopped if self.uid is not None: body["uid"] = self.uid if self.usage_policy_id is not None: body["usage_policy_id"] = self.usage_policy_id return body def as_shallow_dict(self) -> dict: """Serializes the DatabaseInstance into a shallow dictionary of its immediate attributes.""" body = {} if self.capacity is not None: body["capacity"] = self.capacity if self.child_instance_refs: body["child_instance_refs"] = self.child_instance_refs if self.creation_time is not None: body["creation_time"] = self.creation_time if self.creator is not None: body["creator"] = self.creator if self.custom_tags: body["custom_tags"] = self.custom_tags if self.effective_capacity is not None: body["effective_capacity"] = self.effective_capacity if self.effective_custom_tags: body["effective_custom_tags"] = self.effective_custom_tags if self.effective_enable_pg_native_login is not None: body["effective_enable_pg_native_login"] = self.effective_enable_pg_native_login if self.effective_enable_readable_secondaries is not None: body["effective_enable_readable_secondaries"] = self.effective_enable_readable_secondaries if self.effective_node_count is not None: body["effective_node_count"] = self.effective_node_count if self.effective_retention_window_in_days is not None: body["effective_retention_window_in_days"] = self.effective_retention_window_in_days if self.effective_stopped is not None: body["effective_stopped"] = self.effective_stopped if self.effective_usage_policy_id is not None: body["effective_usage_policy_id"] = self.effective_usage_policy_id if self.enable_pg_native_login is not None: body["enable_pg_native_login"] = self.enable_pg_native_login if self.enable_readable_secondaries is not None: body["enable_readable_secondaries"] = self.enable_readable_secondaries if self.name is not None: body["name"] = self.name if self.node_count is not None: body["node_count"] = self.node_count if self.parent_instance_ref: body["parent_instance_ref"] = self.parent_instance_ref if self.pg_version is not None: body["pg_version"] = self.pg_version if self.read_only_dns is not None: body["read_only_dns"] = self.read_only_dns if self.read_write_dns is not None: body["read_write_dns"] = self.read_write_dns if self.retention_window_in_days is not None: body["retention_window_in_days"] = self.retention_window_in_days if self.state is not None: body["state"] = self.state if self.stopped is not None: body["stopped"] = self.stopped if self.uid is not None: body["uid"] = self.uid if self.usage_policy_id is not None: body["usage_policy_id"] = self.usage_policy_id return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> DatabaseInstance: """Deserializes the DatabaseInstance from a dictionary.""" return cls( capacity=d.get("capacity", None), child_instance_refs=_repeated_dict(d, "child_instance_refs", DatabaseInstanceRef), creation_time=d.get("creation_time", None), creator=d.get("creator", None), custom_tags=_repeated_dict(d, "custom_tags", CustomTag), effective_capacity=d.get("effective_capacity", None), effective_custom_tags=_repeated_dict(d, "effective_custom_tags", CustomTag), effective_enable_pg_native_login=d.get("effective_enable_pg_native_login", None), effective_enable_readable_secondaries=d.get("effective_enable_readable_secondaries", None), effective_node_count=d.get("effective_node_count", None), effective_retention_window_in_days=d.get("effective_retention_window_in_days", None), effective_stopped=d.get("effective_stopped", None), effective_usage_policy_id=d.get("effective_usage_policy_id", None), enable_pg_native_login=d.get("enable_pg_native_login", None), enable_readable_secondaries=d.get("enable_readable_secondaries", None), name=d.get("name", None), node_count=d.get("node_count", None), parent_instance_ref=_from_dict(d, "parent_instance_ref", DatabaseInstanceRef), pg_version=d.get("pg_version", None), read_only_dns=d.get("read_only_dns", None), read_write_dns=d.get("read_write_dns", None), retention_window_in_days=d.get("retention_window_in_days", None), state=_enum(d, "state", DatabaseInstanceState), stopped=d.get("stopped", None), uid=d.get("uid", None), usage_policy_id=d.get("usage_policy_id", None), ) @dataclass class DatabaseInstanceRef: """DatabaseInstanceRef is a reference to a database instance. It is used in the DatabaseInstance object to refer to the parent instance of an instance and to refer the child instances of an instance. To specify as a parent instance during creation of an instance, the lsn and branch_time fields are optional. If not specified, the child instance will be created from the latest lsn of the parent. If both lsn and branch_time are specified, the lsn will be used to create the child instance.""" branch_time: Optional[str] = None """Branch time of the ref database instance. For a parent ref instance, this is the point in time on the parent instance from which the instance was created. For a child ref instance, this is the point in time on the instance from which the child instance was created. Input: For specifying the point in time to create a child instance. Optional. Output: Only populated if provided as input to create a child instance.""" effective_lsn: Optional[str] = None """For a parent ref instance, this is the LSN on the parent instance from which the instance was created. For a child ref instance, this is the LSN on the instance from which the child instance was created. This is an output only field that contains the value computed from the input field combined with server side defaults. Use the field without the effective_ prefix to set the value.""" lsn: Optional[str] = None """User-specified WAL LSN of the ref database instance. Input: For specifying the WAL LSN to create a child instance. Optional. Output: Only populated if provided as input to create a child instance.""" name: Optional[str] = None """Name of the ref database instance.""" uid: Optional[str] = None """Id of the ref database instance.""" def as_dict(self) -> dict: """Serializes the DatabaseInstanceRef into a dictionary suitable for use as a JSON request body.""" body = {} if self.branch_time is not None: body["branch_time"] = self.branch_time if self.effective_lsn is not None: body["effective_lsn"] = self.effective_lsn if self.lsn is not None: body["lsn"] = self.lsn if self.name is not None: body["name"] = self.name if self.uid is not None: body["uid"] = self.uid return body def as_shallow_dict(self) -> dict: """Serializes the DatabaseInstanceRef into a shallow dictionary of its immediate attributes.""" body = {} if self.branch_time is not None: body["branch_time"] = self.branch_time if self.effective_lsn is not None: body["effective_lsn"] = self.effective_lsn if self.lsn is not None: body["lsn"] = self.lsn if self.name is not None: body["name"] = self.name if self.uid is not None: body["uid"] = self.uid return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> DatabaseInstanceRef: """Deserializes the DatabaseInstanceRef from a dictionary.""" return cls( branch_time=d.get("branch_time", None), effective_lsn=d.get("effective_lsn", None), lsn=d.get("lsn", None), name=d.get("name", None), uid=d.get("uid", None), ) @dataclass class DatabaseInstanceRole: """A DatabaseInstanceRole represents a Postgres role in a database instance.""" name: str """The name of the role. This is the unique identifier for the role in an instance.""" attributes: Optional[DatabaseInstanceRoleAttributes] = None """The desired API-exposed Postgres role attribute to associate with the role. Optional.""" effective_attributes: Optional[DatabaseInstanceRoleAttributes] = None """The attributes that are applied to the role. This is an output only field that contains the value computed from the input field combined with server side defaults. Use the field without the effective_ prefix to set the value.""" identity_type: Optional[DatabaseInstanceRoleIdentityType] = None """The type of the role.""" instance_name: Optional[str] = None membership_role: Optional[DatabaseInstanceRoleMembershipRole] = None """An enum value for a standard role that this role is a member of.""" def as_dict(self) -> dict: """Serializes the DatabaseInstanceRole into a dictionary suitable for use as a JSON request body.""" body = {} if self.attributes: body["attributes"] = self.attributes.as_dict() if self.effective_attributes: body["effective_attributes"] = self.effective_attributes.as_dict() if self.identity_type is not None: body["identity_type"] = self.identity_type.value if self.instance_name is not None: body["instance_name"] = self.instance_name if self.membership_role is not None: body["membership_role"] = self.membership_role.value if self.name is not None: body["name"] = self.name return body def as_shallow_dict(self) -> dict: """Serializes the DatabaseInstanceRole into a shallow dictionary of its immediate attributes.""" body = {} if self.attributes: body["attributes"] = self.attributes if self.effective_attributes: body["effective_attributes"] = self.effective_attributes if self.identity_type is not None: body["identity_type"] = self.identity_type if self.instance_name is not None: body["instance_name"] = self.instance_name if self.membership_role is not None: body["membership_role"] = self.membership_role if self.name is not None: body["name"] = self.name return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> DatabaseInstanceRole: """Deserializes the DatabaseInstanceRole from a dictionary.""" return cls( attributes=_from_dict(d, "attributes", DatabaseInstanceRoleAttributes), effective_attributes=_from_dict(d, "effective_attributes", DatabaseInstanceRoleAttributes), identity_type=_enum(d, "identity_type", DatabaseInstanceRoleIdentityType), instance_name=d.get("instance_name", None), membership_role=_enum(d, "membership_role", DatabaseInstanceRoleMembershipRole), name=d.get("name", None), ) @dataclass class DatabaseInstanceRoleAttributes: """Attributes that can be granted to a Postgres role. We are only implementing a subset for now, see xref: https://www.postgresql.org/docs/16/sql-createrole.html The values follow Postgres keyword naming e.g. CREATEDB, BYPASSRLS, etc. which is why they don't include typical underscores between words. We were requested to make this a nested object/struct representation since these are knobs from an external spec.""" bypassrls: Optional[bool] = None createdb: Optional[bool] = None createrole: Optional[bool] = None def as_dict(self) -> dict: """Serializes the DatabaseInstanceRoleAttributes into a dictionary suitable for use as a JSON request body.""" body = {} if self.bypassrls is not None: body["bypassrls"] = self.bypassrls if self.createdb is not None: body["createdb"] = self.createdb if self.createrole is not None: body["createrole"] = self.createrole return body def as_shallow_dict(self) -> dict: """Serializes the DatabaseInstanceRoleAttributes into a shallow dictionary of its immediate attributes.""" body = {} if self.bypassrls is not None: body["bypassrls"] = self.bypassrls if self.createdb is not None: body["createdb"] = self.createdb if self.createrole is not None: body["createrole"] = self.createrole return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> DatabaseInstanceRoleAttributes: """Deserializes the DatabaseInstanceRoleAttributes from a dictionary.""" return cls( bypassrls=d.get("bypassrls", None), createdb=d.get("createdb", None), createrole=d.get("createrole", None) ) class DatabaseInstanceRoleIdentityType(Enum): GROUP = "GROUP" PG_ONLY = "PG_ONLY" SERVICE_PRINCIPAL = "SERVICE_PRINCIPAL" USER = "USER" class DatabaseInstanceRoleMembershipRole(Enum): """Roles that the DatabaseInstanceRole can be a member of.""" DATABRICKS_SUPERUSER = "DATABRICKS_SUPERUSER" class DatabaseInstanceState(Enum): AVAILABLE = "AVAILABLE" DELETING = "DELETING" FAILING_OVER = "FAILING_OVER" STARTING = "STARTING" STOPPED = "STOPPED" UPDATING = "UPDATING" @dataclass class DatabaseTable: """Next field marker: 13""" name: str """Full three-part (catalog, schema, table) name of the table.""" database_instance_name: Optional[str] = None """Name of the target database instance. This is required when creating database tables in standard catalogs. This is optional when creating database tables in registered catalogs. If this field is specified when creating database tables in registered catalogs, the database instance name MUST match that of the registered catalog (or the request will be rejected).""" logical_database_name: Optional[str] = None """Target Postgres database object (logical database) name for this table. When creating a table in a standard catalog, this field is required. In this scenario, specifying this field will allow targeting an arbitrary postgres database. Registration of database tables via /database/tables is currently only supported in standard catalogs.""" def as_dict(self) -> dict: """Serializes the DatabaseTable into a dictionary suitable for use as a JSON request body.""" body = {} if self.database_instance_name is not None: body["database_instance_name"] = self.database_instance_name if self.logical_database_name is not None: body["logical_database_name"] = self.logical_database_name if self.name is not None: body["name"] = self.name return body def as_shallow_dict(self) -> dict: """Serializes the DatabaseTable into a shallow dictionary of its immediate attributes.""" body = {} if self.database_instance_name is not None: body["database_instance_name"] = self.database_instance_name if self.logical_database_name is not None: body["logical_database_name"] = self.logical_database_name if self.name is not None: body["name"] = self.name return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> DatabaseTable: """Deserializes the DatabaseTable from a dictionary.""" return cls( database_instance_name=d.get("database_instance_name", None), logical_database_name=d.get("logical_database_name", None), name=d.get("name", None), ) @dataclass class DeltaTableSyncInfo: delta_commit_timestamp: Optional[str] = None """The timestamp when the above Delta version was committed in the source Delta table. Note: This is the Delta commit time, not the time the data was written to the synced table.""" delta_commit_version: Optional[int] = None """The Delta Lake commit version that was last successfully synced.""" def as_dict(self) -> dict: """Serializes the DeltaTableSyncInfo into a dictionary suitable for use as a JSON request body.""" body = {} if self.delta_commit_timestamp is not None: body["delta_commit_timestamp"] = self.delta_commit_timestamp if self.delta_commit_version is not None: body["delta_commit_version"] = self.delta_commit_version return body def as_shallow_dict(self) -> dict: """Serializes the DeltaTableSyncInfo into a shallow dictionary of its immediate attributes.""" body = {} if self.delta_commit_timestamp is not None: body["delta_commit_timestamp"] = self.delta_commit_timestamp if self.delta_commit_version is not None: body["delta_commit_version"] = self.delta_commit_version return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> DeltaTableSyncInfo: """Deserializes the DeltaTableSyncInfo from a dictionary.""" return cls( delta_commit_timestamp=d.get("delta_commit_timestamp", None), delta_commit_version=d.get("delta_commit_version", None), ) @dataclass class ListDatabaseCatalogsResponse: database_catalogs: Optional[List[DatabaseCatalog]] = None next_page_token: Optional[str] = None """Pagination token to request the next page of database catalogs.""" def as_dict(self) -> dict: """Serializes the ListDatabaseCatalogsResponse into a dictionary suitable for use as a JSON request body.""" body = {} if self.database_catalogs: body["database_catalogs"] = [v.as_dict() for v in self.database_catalogs] if self.next_page_token is not None: body["next_page_token"] = self.next_page_token return body def as_shallow_dict(self) -> dict: """Serializes the ListDatabaseCatalogsResponse into a shallow dictionary of its immediate attributes.""" body = {} if self.database_catalogs: body["database_catalogs"] = self.database_catalogs if self.next_page_token is not None: body["next_page_token"] = self.next_page_token return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> ListDatabaseCatalogsResponse: """Deserializes the ListDatabaseCatalogsResponse from a dictionary.""" return cls( database_catalogs=_repeated_dict(d, "database_catalogs", DatabaseCatalog), next_page_token=d.get("next_page_token", None), ) @dataclass class ListDatabaseInstanceRolesResponse: database_instance_roles: Optional[List[DatabaseInstanceRole]] = None """List of database instance roles.""" next_page_token: Optional[str] = None """Pagination token to request the next page of instances.""" def as_dict(self) -> dict: """Serializes the ListDatabaseInstanceRolesResponse into a dictionary suitable for use as a JSON request body.""" body = {} if self.database_instance_roles: body["database_instance_roles"] = [v.as_dict() for v in self.database_instance_roles] if self.next_page_token is not None: body["next_page_token"] = self.next_page_token return body def as_shallow_dict(self) -> dict: """Serializes the ListDatabaseInstanceRolesResponse into a shallow dictionary of its immediate attributes.""" body = {} if self.database_instance_roles: body["database_instance_roles"] = self.database_instance_roles if self.next_page_token is not None: body["next_page_token"] = self.next_page_token return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> ListDatabaseInstanceRolesResponse: """Deserializes the ListDatabaseInstanceRolesResponse from a dictionary.""" return cls( database_instance_roles=_repeated_dict(d, "database_instance_roles", DatabaseInstanceRole), next_page_token=d.get("next_page_token", None), ) @dataclass class ListDatabaseInstancesResponse: database_instances: Optional[List[DatabaseInstance]] = None """List of instances.""" next_page_token: Optional[str] = None """Pagination token to request the next page of instances.""" def as_dict(self) -> dict: """Serializes the ListDatabaseInstancesResponse into a dictionary suitable for use as a JSON request body.""" body = {} if self.database_instances: body["database_instances"] = [v.as_dict() for v in self.database_instances] if self.next_page_token is not None: body["next_page_token"] = self.next_page_token return body def as_shallow_dict(self) -> dict: """Serializes the ListDatabaseInstancesResponse into a shallow dictionary of its immediate attributes.""" body = {} if self.database_instances: body["database_instances"] = self.database_instances if self.next_page_token is not None: body["next_page_token"] = self.next_page_token return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> ListDatabaseInstancesResponse: """Deserializes the ListDatabaseInstancesResponse from a dictionary.""" return cls( database_instances=_repeated_dict(d, "database_instances", DatabaseInstance), next_page_token=d.get("next_page_token", None), ) @dataclass class ListSyncedDatabaseTablesResponse: next_page_token: Optional[str] = None """Pagination token to request the next page of synced tables.""" synced_tables: Optional[List[SyncedDatabaseTable]] = None def as_dict(self) -> dict: """Serializes the ListSyncedDatabaseTablesResponse into a dictionary suitable for use as a JSON request body.""" body = {} if self.next_page_token is not None: body["next_page_token"] = self.next_page_token if self.synced_tables: body["synced_tables"] = [v.as_dict() for v in self.synced_tables] return body def as_shallow_dict(self) -> dict: """Serializes the ListSyncedDatabaseTablesResponse into a shallow dictionary of its immediate attributes.""" body = {} if self.next_page_token is not None: body["next_page_token"] = self.next_page_token if self.synced_tables: body["synced_tables"] = self.synced_tables return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> ListSyncedDatabaseTablesResponse: """Deserializes the ListSyncedDatabaseTablesResponse from a dictionary.""" return cls( next_page_token=d.get("next_page_token", None), synced_tables=_repeated_dict(d, "synced_tables", SyncedDatabaseTable), ) @dataclass class NewPipelineSpec: """Custom fields that user can set for pipeline while creating SyncedDatabaseTable. Note that other fields of pipeline are still inferred by table def internally""" budget_policy_id: Optional[str] = None """Budget policy to set on the newly created pipeline.""" storage_catalog: Optional[str] = None """This field needs to be specified if the destination catalog is a managed postgres catalog. UC catalog for the pipeline to store intermediate files (checkpoints, event logs etc). This needs to be a standard catalog where the user has permissions to create Delta tables.""" storage_schema: Optional[str] = None """This field needs to be specified if the destination catalog is a managed postgres catalog. UC schema for the pipeline to store intermediate files (checkpoints, event logs etc). This needs to be in the standard catalog where the user has permissions to create Delta tables.""" def as_dict(self) -> dict: """Serializes the NewPipelineSpec into a dictionary suitable for use as a JSON request body.""" body = {} if self.budget_policy_id is not None: body["budget_policy_id"] = self.budget_policy_id if self.storage_catalog is not None: body["storage_catalog"] = self.storage_catalog if self.storage_schema is not None: body["storage_schema"] = self.storage_schema return body def as_shallow_dict(self) -> dict: """Serializes the NewPipelineSpec into a shallow dictionary of its immediate attributes.""" body = {} if self.budget_policy_id is not None: body["budget_policy_id"] = self.budget_policy_id if self.storage_catalog is not None: body["storage_catalog"] = self.storage_catalog if self.storage_schema is not None: body["storage_schema"] = self.storage_schema return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> NewPipelineSpec: """Deserializes the NewPipelineSpec from a dictionary.""" return cls( budget_policy_id=d.get("budget_policy_id", None), storage_catalog=d.get("storage_catalog", None), storage_schema=d.get("storage_schema", None), ) class ProvisioningInfoState(Enum): ACTIVE = "ACTIVE" DEGRADED = "DEGRADED" DELETING = "DELETING" FAILED = "FAILED" PROVISIONING = "PROVISIONING" UPDATING = "UPDATING" class ProvisioningPhase(Enum): PROVISIONING_PHASE_INDEX_SCAN = "PROVISIONING_PHASE_INDEX_SCAN" PROVISIONING_PHASE_INDEX_SORT = "PROVISIONING_PHASE_INDEX_SORT" PROVISIONING_PHASE_MAIN = "PROVISIONING_PHASE_MAIN" @dataclass class RequestedClaims: permission_set: Optional[RequestedClaimsPermissionSet] = None resources: Optional[List[RequestedResource]] = None def as_dict(self) -> dict: """Serializes the RequestedClaims into a dictionary suitable for use as a JSON request body.""" body = {} if self.permission_set is not None: body["permission_set"] = self.permission_set.value if self.resources: body["resources"] = [v.as_dict() for v in self.resources] return body def as_shallow_dict(self) -> dict: """Serializes the RequestedClaims into a shallow dictionary of its immediate attributes.""" body = {} if self.permission_set is not None: body["permission_set"] = self.permission_set if self.resources: body["resources"] = self.resources return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> RequestedClaims: """Deserializes the RequestedClaims from a dictionary.""" return cls( permission_set=_enum(d, "permission_set", RequestedClaimsPermissionSet), resources=_repeated_dict(d, "resources", RequestedResource), ) class RequestedClaimsPermissionSet(Enum): """Might add WRITE in the future""" READ_ONLY = "READ_ONLY" @dataclass class RequestedResource: table_name: Optional[str] = None unspecified_resource_name: Optional[str] = None def as_dict(self) -> dict: """Serializes the RequestedResource into a dictionary suitable for use as a JSON request body.""" body = {} if self.table_name is not None: body["table_name"] = self.table_name if self.unspecified_resource_name is not None: body["unspecified_resource_name"] = self.unspecified_resource_name return body def as_shallow_dict(self) -> dict: """Serializes the RequestedResource into a shallow dictionary of its immediate attributes.""" body = {} if self.table_name is not None: body["table_name"] = self.table_name if self.unspecified_resource_name is not None: body["unspecified_resource_name"] = self.unspecified_resource_name return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> RequestedResource: """Deserializes the RequestedResource from a dictionary.""" return cls( table_name=d.get("table_name", None), unspecified_resource_name=d.get("unspecified_resource_name", None) ) @dataclass class SyncedDatabaseTable: """Next field marker: 18""" name: str """Full three-part (catalog, schema, table) name of the table.""" data_synchronization_status: Optional[SyncedTableStatus] = None """Synced Table data synchronization status""" database_instance_name: Optional[str] = None """Name of the target database instance. This is required when creating synced database tables in standard catalogs. This is optional when creating synced database tables in registered catalogs. If this field is specified when creating synced database tables in registered catalogs, the database instance name MUST match that of the registered catalog (or the request will be rejected).""" effective_database_instance_name: Optional[str] = None """The name of the database instance that this table is registered to. This field is always returned, and for tables inside database catalogs is inferred database instance associated with the catalog. This is an output only field that contains the value computed from the input field combined with server side defaults. Use the field without the effective_ prefix to set the value.""" effective_logical_database_name: Optional[str] = None """The name of the logical database that this table is registered to. This is an output only field that contains the value computed from the input field combined with server side defaults. Use the field without the effective_ prefix to set the value.""" logical_database_name: Optional[str] = None """Target Postgres database object (logical database) name for this table. When creating a synced table in a registered Postgres catalog, the target Postgres database name is inferred to be that of the registered catalog. If this field is specified in this scenario, the Postgres database name MUST match that of the registered catalog (or the request will be rejected). When creating a synced table in a standard catalog, this field is required. In this scenario, specifying this field will allow targeting an arbitrary postgres database. Note that this has implications for the `create_database_objects_is_missing` field in `spec`.""" spec: Optional[SyncedTableSpec] = None unity_catalog_provisioning_state: Optional[ProvisioningInfoState] = None """The provisioning state of the synced table entity in Unity Catalog. This is distinct from the state of the data synchronization pipeline (i.e. the table may be in "ACTIVE" but the pipeline may be in "PROVISIONING" as it runs asynchronously).""" def as_dict(self) -> dict: """Serializes the SyncedDatabaseTable into a dictionary suitable for use as a JSON request body.""" body = {} if self.data_synchronization_status: body["data_synchronization_status"] = self.data_synchronization_status.as_dict() if self.database_instance_name is not None: body["database_instance_name"] = self.database_instance_name if self.effective_database_instance_name is not None: body["effective_database_instance_name"] = self.effective_database_instance_name if self.effective_logical_database_name is not None: body["effective_logical_database_name"] = self.effective_logical_database_name if self.logical_database_name is not None: body["logical_database_name"] = self.logical_database_name if self.name is not None: body["name"] = self.name if self.spec: body["spec"] = self.spec.as_dict() if self.unity_catalog_provisioning_state is not None: body["unity_catalog_provisioning_state"] = self.unity_catalog_provisioning_state.value return body def as_shallow_dict(self) -> dict: """Serializes the SyncedDatabaseTable into a shallow dictionary of its immediate attributes.""" body = {} if self.data_synchronization_status: body["data_synchronization_status"] = self.data_synchronization_status if self.database_instance_name is not None: body["database_instance_name"] = self.database_instance_name if self.effective_database_instance_name is not None: body["effective_database_instance_name"] = self.effective_database_instance_name if self.effective_logical_database_name is not None: body["effective_logical_database_name"] = self.effective_logical_database_name if self.logical_database_name is not None: body["logical_database_name"] = self.logical_database_name if self.name is not None: body["name"] = self.name if self.spec: body["spec"] = self.spec if self.unity_catalog_provisioning_state is not None: body["unity_catalog_provisioning_state"] = self.unity_catalog_provisioning_state return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> SyncedDatabaseTable: """Deserializes the SyncedDatabaseTable from a dictionary.""" return cls( data_synchronization_status=_from_dict(d, "data_synchronization_status", SyncedTableStatus), database_instance_name=d.get("database_instance_name", None), effective_database_instance_name=d.get("effective_database_instance_name", None), effective_logical_database_name=d.get("effective_logical_database_name", None), logical_database_name=d.get("logical_database_name", None), name=d.get("name", None), spec=_from_dict(d, "spec", SyncedTableSpec), unity_catalog_provisioning_state=_enum(d, "unity_catalog_provisioning_state", ProvisioningInfoState), ) @dataclass class SyncedTableContinuousUpdateStatus: """Detailed status of a synced table. Shown if the synced table is in the SYNCED_CONTINUOUS_UPDATE or the SYNCED_UPDATING_PIPELINE_RESOURCES state.""" initial_pipeline_sync_progress: Optional[SyncedTablePipelineProgress] = None """Progress of the initial data synchronization.""" last_processed_commit_version: Optional[int] = None """The last source table Delta version that was successfully synced to the synced table.""" timestamp: Optional[str] = None """The end timestamp of the last time any data was synchronized from the source table to the synced table. This is when the data is available in the synced table.""" def as_dict(self) -> dict: """Serializes the SyncedTableContinuousUpdateStatus into a dictionary suitable for use as a JSON request body.""" body = {} if self.initial_pipeline_sync_progress: body["initial_pipeline_sync_progress"] = self.initial_pipeline_sync_progress.as_dict() if self.last_processed_commit_version is not None: body["last_processed_commit_version"] = self.last_processed_commit_version if self.timestamp is not None: body["timestamp"] = self.timestamp return body def as_shallow_dict(self) -> dict: """Serializes the SyncedTableContinuousUpdateStatus into a shallow dictionary of its immediate attributes.""" body = {} if self.initial_pipeline_sync_progress: body["initial_pipeline_sync_progress"] = self.initial_pipeline_sync_progress if self.last_processed_commit_version is not None: body["last_processed_commit_version"] = self.last_processed_commit_version if self.timestamp is not None: body["timestamp"] = self.timestamp return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> SyncedTableContinuousUpdateStatus: """Deserializes the SyncedTableContinuousUpdateStatus from a dictionary.""" return cls( initial_pipeline_sync_progress=_from_dict(d, "initial_pipeline_sync_progress", SyncedTablePipelineProgress), last_processed_commit_version=d.get("last_processed_commit_version", None), timestamp=d.get("timestamp", None), ) @dataclass class SyncedTableFailedStatus: """Detailed status of a synced table. Shown if the synced table is in the OFFLINE_FAILED or the SYNCED_PIPELINE_FAILED state.""" last_processed_commit_version: Optional[int] = None """The last source table Delta version that was successfully synced to the synced table. The last source table Delta version that was synced to the synced table. Only populated if the table is still synced and available for serving.""" timestamp: Optional[str] = None """The end timestamp of the last time any data was synchronized from the source table to the synced table. Only populated if the table is still synced and available for serving.""" def as_dict(self) -> dict: """Serializes the SyncedTableFailedStatus into a dictionary suitable for use as a JSON request body.""" body = {} if self.last_processed_commit_version is not None: body["last_processed_commit_version"] = self.last_processed_commit_version if self.timestamp is not None: body["timestamp"] = self.timestamp return body def as_shallow_dict(self) -> dict: """Serializes the SyncedTableFailedStatus into a shallow dictionary of its immediate attributes.""" body = {} if self.last_processed_commit_version is not None: body["last_processed_commit_version"] = self.last_processed_commit_version if self.timestamp is not None: body["timestamp"] = self.timestamp return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> SyncedTableFailedStatus: """Deserializes the SyncedTableFailedStatus from a dictionary.""" return cls( last_processed_commit_version=d.get("last_processed_commit_version", None), timestamp=d.get("timestamp", None), ) @dataclass class SyncedTablePipelineProgress: """Progress information of the Synced Table data synchronization pipeline.""" estimated_completion_time_seconds: Optional[float] = None """The estimated time remaining to complete this update in seconds.""" latest_version_currently_processing: Optional[int] = None """The source table Delta version that was last processed by the pipeline. The pipeline may not have completely processed this version yet.""" provisioning_phase: Optional[ProvisioningPhase] = None """The current phase of the data synchronization pipeline.""" sync_progress_completion: Optional[float] = None """The completion ratio of this update. This is a number between 0 and 1.""" synced_row_count: Optional[int] = None """The number of rows that have been synced in this update.""" total_row_count: Optional[int] = None """The total number of rows that need to be synced in this update. This number may be an estimate.""" def as_dict(self) -> dict: """Serializes the SyncedTablePipelineProgress into a dictionary suitable for use as a JSON request body.""" body = {} if self.estimated_completion_time_seconds is not None: body["estimated_completion_time_seconds"] = self.estimated_completion_time_seconds if self.latest_version_currently_processing is not None: body["latest_version_currently_processing"] = self.latest_version_currently_processing if self.provisioning_phase is not None: body["provisioning_phase"] = self.provisioning_phase.value if self.sync_progress_completion is not None: body["sync_progress_completion"] = self.sync_progress_completion if self.synced_row_count is not None: body["synced_row_count"] = self.synced_row_count if self.total_row_count is not None: body["total_row_count"] = self.total_row_count return body def as_shallow_dict(self) -> dict: """Serializes the SyncedTablePipelineProgress into a shallow dictionary of its immediate attributes.""" body = {} if self.estimated_completion_time_seconds is not None: body["estimated_completion_time_seconds"] = self.estimated_completion_time_seconds if self.latest_version_currently_processing is not None: body["latest_version_currently_processing"] = self.latest_version_currently_processing if self.provisioning_phase is not None: body["provisioning_phase"] = self.provisioning_phase if self.sync_progress_completion is not None: body["sync_progress_completion"] = self.sync_progress_completion if self.synced_row_count is not None: body["synced_row_count"] = self.synced_row_count if self.total_row_count is not None: body["total_row_count"] = self.total_row_count return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> SyncedTablePipelineProgress: """Deserializes the SyncedTablePipelineProgress from a dictionary.""" return cls( estimated_completion_time_seconds=d.get("estimated_completion_time_seconds", None), latest_version_currently_processing=d.get("latest_version_currently_processing", None), provisioning_phase=_enum(d, "provisioning_phase", ProvisioningPhase), sync_progress_completion=d.get("sync_progress_completion", None), synced_row_count=d.get("synced_row_count", None), total_row_count=d.get("total_row_count", None), ) @dataclass class SyncedTablePosition: delta_table_sync_info: Optional[DeltaTableSyncInfo] = None sync_end_timestamp: Optional[str] = None """The end timestamp of the most recent successful synchronization. This is the time when the data is available in the synced table.""" sync_start_timestamp: Optional[str] = None """The starting timestamp of the most recent successful synchronization from the source table to the destination (synced) table. Note this is the starting timestamp of the sync operation, not the end time. E.g., for a batch, this is the time when the sync operation started.""" def as_dict(self) -> dict: """Serializes the SyncedTablePosition into a dictionary suitable for use as a JSON request body.""" body = {} if self.delta_table_sync_info: body["delta_table_sync_info"] = self.delta_table_sync_info.as_dict() if self.sync_end_timestamp is not None: body["sync_end_timestamp"] = self.sync_end_timestamp if self.sync_start_timestamp is not None: body["sync_start_timestamp"] = self.sync_start_timestamp return body def as_shallow_dict(self) -> dict: """Serializes the SyncedTablePosition into a shallow dictionary of its immediate attributes.""" body = {} if self.delta_table_sync_info: body["delta_table_sync_info"] = self.delta_table_sync_info if self.sync_end_timestamp is not None: body["sync_end_timestamp"] = self.sync_end_timestamp if self.sync_start_timestamp is not None: body["sync_start_timestamp"] = self.sync_start_timestamp return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> SyncedTablePosition: """Deserializes the SyncedTablePosition from a dictionary.""" return cls( delta_table_sync_info=_from_dict(d, "delta_table_sync_info", DeltaTableSyncInfo), sync_end_timestamp=d.get("sync_end_timestamp", None), sync_start_timestamp=d.get("sync_start_timestamp", None), ) @dataclass class SyncedTableProvisioningStatus: """Detailed status of a synced table. Shown if the synced table is in the PROVISIONING_PIPELINE_RESOURCES or the PROVISIONING_INITIAL_SNAPSHOT state.""" initial_pipeline_sync_progress: Optional[SyncedTablePipelineProgress] = None """Details about initial data synchronization. Only populated when in the PROVISIONING_INITIAL_SNAPSHOT state.""" def as_dict(self) -> dict: """Serializes the SyncedTableProvisioningStatus into a dictionary suitable for use as a JSON request body.""" body = {} if self.initial_pipeline_sync_progress: body["initial_pipeline_sync_progress"] = self.initial_pipeline_sync_progress.as_dict() return body def as_shallow_dict(self) -> dict: """Serializes the SyncedTableProvisioningStatus into a shallow dictionary of its immediate attributes.""" body = {} if self.initial_pipeline_sync_progress: body["initial_pipeline_sync_progress"] = self.initial_pipeline_sync_progress return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> SyncedTableProvisioningStatus: """Deserializes the SyncedTableProvisioningStatus from a dictionary.""" return cls( initial_pipeline_sync_progress=_from_dict(d, "initial_pipeline_sync_progress", SyncedTablePipelineProgress) ) class SyncedTableSchedulingPolicy(Enum): CONTINUOUS = "CONTINUOUS" SNAPSHOT = "SNAPSHOT" TRIGGERED = "TRIGGERED" @dataclass class SyncedTableSpec: """Specification of a synced database table.""" create_database_objects_if_missing: Optional[bool] = None """If true, the synced table's logical database and schema resources in PG will be created if they do not already exist.""" existing_pipeline_id: Optional[str] = None """At most one of existing_pipeline_id and new_pipeline_spec should be defined. If existing_pipeline_id is defined, the synced table will be bin packed into the existing pipeline referenced. This avoids creating a new pipeline and allows sharing existing compute. In this case, the scheduling_policy of this synced table must match the scheduling policy of the existing pipeline.""" new_pipeline_spec: Optional[NewPipelineSpec] = None """At most one of existing_pipeline_id and new_pipeline_spec should be defined. If new_pipeline_spec is defined, a new pipeline is created for this synced table. The location pointed to is used to store intermediate files (checkpoints, event logs etc). The caller must have write permissions to create Delta tables in the specified catalog and schema. Again, note this requires write permissions, whereas the source table only requires read permissions.""" primary_key_columns: Optional[List[str]] = None """Primary Key columns to be used for data insert/update in the destination.""" scheduling_policy: Optional[SyncedTableSchedulingPolicy] = None """Scheduling policy of the underlying pipeline.""" source_table_full_name: Optional[str] = None """Three-part (catalog, schema, table) name of the source Delta table.""" timeseries_key: Optional[str] = None """Time series key to deduplicate (tie-break) rows with the same primary key.""" def as_dict(self) -> dict: """Serializes the SyncedTableSpec into a dictionary suitable for use as a JSON request body.""" body = {} if self.create_database_objects_if_missing is not None: body["create_database_objects_if_missing"] = self.create_database_objects_if_missing if self.existing_pipeline_id is not None: body["existing_pipeline_id"] = self.existing_pipeline_id if self.new_pipeline_spec: body["new_pipeline_spec"] = self.new_pipeline_spec.as_dict() if self.primary_key_columns: body["primary_key_columns"] = [v for v in self.primary_key_columns] if self.scheduling_policy is not None: body["scheduling_policy"] = self.scheduling_policy.value if self.source_table_full_name is not None: body["source_table_full_name"] = self.source_table_full_name if self.timeseries_key is not None: body["timeseries_key"] = self.timeseries_key return body def as_shallow_dict(self) -> dict: """Serializes the SyncedTableSpec into a shallow dictionary of its immediate attributes.""" body = {} if self.create_database_objects_if_missing is not None: body["create_database_objects_if_missing"] = self.create_database_objects_if_missing if self.existing_pipeline_id is not None: body["existing_pipeline_id"] = self.existing_pipeline_id if self.new_pipeline_spec: body["new_pipeline_spec"] = self.new_pipeline_spec if self.primary_key_columns: body["primary_key_columns"] = self.primary_key_columns if self.scheduling_policy is not None: body["scheduling_policy"] = self.scheduling_policy if self.source_table_full_name is not None: body["source_table_full_name"] = self.source_table_full_name if self.timeseries_key is not None: body["timeseries_key"] = self.timeseries_key return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> SyncedTableSpec: """Deserializes the SyncedTableSpec from a dictionary.""" return cls( create_database_objects_if_missing=d.get("create_database_objects_if_missing", None), existing_pipeline_id=d.get("existing_pipeline_id", None), new_pipeline_spec=_from_dict(d, "new_pipeline_spec", NewPipelineSpec), primary_key_columns=d.get("primary_key_columns", None), scheduling_policy=_enum(d, "scheduling_policy", SyncedTableSchedulingPolicy), source_table_full_name=d.get("source_table_full_name", None), timeseries_key=d.get("timeseries_key", None), ) class SyncedTableState(Enum): """The state of a synced table.""" SYNCED_TABLED_OFFLINE = "SYNCED_TABLED_OFFLINE" SYNCED_TABLE_OFFLINE_FAILED = "SYNCED_TABLE_OFFLINE_FAILED" SYNCED_TABLE_ONLINE = "SYNCED_TABLE_ONLINE" SYNCED_TABLE_ONLINE_CONTINUOUS_UPDATE = "SYNCED_TABLE_ONLINE_CONTINUOUS_UPDATE" SYNCED_TABLE_ONLINE_NO_PENDING_UPDATE = "SYNCED_TABLE_ONLINE_NO_PENDING_UPDATE" SYNCED_TABLE_ONLINE_PIPELINE_FAILED = "SYNCED_TABLE_ONLINE_PIPELINE_FAILED" SYNCED_TABLE_ONLINE_TRIGGERED_UPDATE = "SYNCED_TABLE_ONLINE_TRIGGERED_UPDATE" SYNCED_TABLE_ONLINE_UPDATING_PIPELINE_RESOURCES = "SYNCED_TABLE_ONLINE_UPDATING_PIPELINE_RESOURCES" SYNCED_TABLE_PROVISIONING = "SYNCED_TABLE_PROVISIONING" SYNCED_TABLE_PROVISIONING_INITIAL_SNAPSHOT = "SYNCED_TABLE_PROVISIONING_INITIAL_SNAPSHOT" SYNCED_TABLE_PROVISIONING_PIPELINE_RESOURCES = "SYNCED_TABLE_PROVISIONING_PIPELINE_RESOURCES" @dataclass class SyncedTableStatus: """Status of a synced table.""" continuous_update_status: Optional[SyncedTableContinuousUpdateStatus] = None detailed_state: Optional[SyncedTableState] = None """The state of the synced table.""" failed_status: Optional[SyncedTableFailedStatus] = None last_sync: Optional[SyncedTablePosition] = None """Summary of the last successful synchronization from source to destination. Will always be present if there has been a successful sync. Even if the most recent syncs have failed. Limitation: The only exception is if the synced table is doing a FULL REFRESH, then the last sync information will not be available until the full refresh is complete. This limitation will be addressed in a future version. This top-level field is a convenience for consumers who want easy access to last sync information without having to traverse detailed_status.""" message: Optional[str] = None """A text description of the current state of the synced table.""" pipeline_id: Optional[str] = None """ID of the associated pipeline. The pipeline ID may have been provided by the client (in the case of bin packing), or generated by the server (when creating a new pipeline).""" provisioning_status: Optional[SyncedTableProvisioningStatus] = None triggered_update_status: Optional[SyncedTableTriggeredUpdateStatus] = None def as_dict(self) -> dict: """Serializes the SyncedTableStatus into a dictionary suitable for use as a JSON request body.""" body = {} if self.continuous_update_status: body["continuous_update_status"] = self.continuous_update_status.as_dict() if self.detailed_state is not None: body["detailed_state"] = self.detailed_state.value if self.failed_status: body["failed_status"] = self.failed_status.as_dict() if self.last_sync: body["last_sync"] = self.last_sync.as_dict() if self.message is not None: body["message"] = self.message if self.pipeline_id is not None: body["pipeline_id"] = self.pipeline_id if self.provisioning_status: body["provisioning_status"] = self.provisioning_status.as_dict() if self.triggered_update_status: body["triggered_update_status"] = self.triggered_update_status.as_dict() return body def as_shallow_dict(self) -> dict: """Serializes the SyncedTableStatus into a shallow dictionary of its immediate attributes.""" body = {} if self.continuous_update_status: body["continuous_update_status"] = self.continuous_update_status if self.detailed_state is not None: body["detailed_state"] = self.detailed_state if self.failed_status: body["failed_status"] = self.failed_status if self.last_sync: body["last_sync"] = self.last_sync if self.message is not None: body["message"] = self.message if self.pipeline_id is not None: body["pipeline_id"] = self.pipeline_id if self.provisioning_status: body["provisioning_status"] = self.provisioning_status if self.triggered_update_status: body["triggered_update_status"] = self.triggered_update_status return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> SyncedTableStatus: """Deserializes the SyncedTableStatus from a dictionary.""" return cls( continuous_update_status=_from_dict(d, "continuous_update_status", SyncedTableContinuousUpdateStatus), detailed_state=_enum(d, "detailed_state", SyncedTableState), failed_status=_from_dict(d, "failed_status", SyncedTableFailedStatus), last_sync=_from_dict(d, "last_sync", SyncedTablePosition), message=d.get("message", None), pipeline_id=d.get("pipeline_id", None), provisioning_status=_from_dict(d, "provisioning_status", SyncedTableProvisioningStatus), triggered_update_status=_from_dict(d, "triggered_update_status", SyncedTableTriggeredUpdateStatus), ) @dataclass class SyncedTableTriggeredUpdateStatus: """Detailed status of a synced table. Shown if the synced table is in the SYNCED_TRIGGERED_UPDATE or the SYNCED_NO_PENDING_UPDATE state.""" last_processed_commit_version: Optional[int] = None """The last source table Delta version that was successfully synced to the synced table.""" timestamp: Optional[str] = None """The end timestamp of the last time any data was synchronized from the source table to the synced table. This is when the data is available in the synced table.""" triggered_update_progress: Optional[SyncedTablePipelineProgress] = None """Progress of the active data synchronization pipeline.""" def as_dict(self) -> dict: """Serializes the SyncedTableTriggeredUpdateStatus into a dictionary suitable for use as a JSON request body.""" body = {} if self.last_processed_commit_version is not None: body["last_processed_commit_version"] = self.last_processed_commit_version if self.timestamp is not None: body["timestamp"] = self.timestamp if self.triggered_update_progress: body["triggered_update_progress"] = self.triggered_update_progress.as_dict() return body def as_shallow_dict(self) -> dict: """Serializes the SyncedTableTriggeredUpdateStatus into a shallow dictionary of its immediate attributes.""" body = {} if self.last_processed_commit_version is not None: body["last_processed_commit_version"] = self.last_processed_commit_version if self.timestamp is not None: body["timestamp"] = self.timestamp if self.triggered_update_progress: body["triggered_update_progress"] = self.triggered_update_progress return body @classmethod def from_dict(cls, d: Dict[str, Any]) -> SyncedTableTriggeredUpdateStatus: """Deserializes the SyncedTableTriggeredUpdateStatus from a dictionary.""" return cls( last_processed_commit_version=d.get("last_processed_commit_version", None), timestamp=d.get("timestamp", None), triggered_update_progress=_from_dict(d, "triggered_update_progress", SyncedTablePipelineProgress), ) class DatabaseAPI: """Database Instances provide access to a database via REST API or direct SQL.""" def __init__(self, api_client): self._api = api_client def wait_get_database_instance_database_available( self, name: str, timeout=timedelta(minutes=20), callback: Optional[Callable[[DatabaseInstance], None]] = None ) -> DatabaseInstance: deadline = time.time() + timeout.total_seconds() target_states = (DatabaseInstanceState.AVAILABLE,) status_message = "polling..." attempt = 1 while time.time() < deadline: poll = self.get_database_instance(name=name) status = poll.state status_message = f"current status: {status}" if status in target_states: return poll if callback: callback(poll) prefix = f"name={name}" sleep = attempt if sleep > 10: # sleep 10s max per attempt sleep = 10 _LOG.debug(f"{prefix}: ({status}) {status_message} (sleeping ~{sleep}s)") time.sleep(sleep + random.random()) attempt += 1 raise TimeoutError(f"timed out after {timeout}: {status_message}") def create_database_catalog(self, catalog: DatabaseCatalog) -> DatabaseCatalog: """Create a Database Catalog. :param catalog: :class:`DatabaseCatalog` :returns: :class:`DatabaseCatalog` """ body = catalog.as_dict() headers = { "Accept": "application/json", "Content-Type": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id res = self._api.do("POST", "/api/2.0/database/catalogs", body=body, headers=headers) return DatabaseCatalog.from_dict(res) def create_database_instance(self, database_instance: DatabaseInstance) -> Wait[DatabaseInstance]: """Create a Database Instance. :param database_instance: :class:`DatabaseInstance` Instance to create. :returns: Long-running operation waiter for :class:`DatabaseInstance`. See :method:wait_get_database_instance_database_available for more details. """ body = database_instance.as_dict() headers = { "Accept": "application/json", "Content-Type": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id op_response = self._api.do("POST", "/api/2.0/database/instances", body=body, headers=headers) return Wait( self.wait_get_database_instance_database_available, response=DatabaseInstance.from_dict(op_response), name=op_response["name"], ) def create_database_instance_and_wait( self, database_instance: DatabaseInstance, timeout=timedelta(minutes=20) ) -> DatabaseInstance: return self.create_database_instance(database_instance=database_instance).result(timeout=timeout) def create_database_instance_role( self, instance_name: str, database_instance_role: DatabaseInstanceRole, *, database_instance_name: Optional[str] = None, ) -> DatabaseInstanceRole: """Create a role for a Database Instance. :param instance_name: str :param database_instance_role: :class:`DatabaseInstanceRole` :param database_instance_name: str (optional) :returns: :class:`DatabaseInstanceRole` """ body = database_instance_role.as_dict() query = {} if database_instance_name is not None: query["database_instance_name"] = database_instance_name headers = { "Accept": "application/json", "Content-Type": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id res = self._api.do( "POST", f"/api/2.0/database/instances/{instance_name}/roles", query=query, body=body, headers=headers ) return DatabaseInstanceRole.from_dict(res) def create_database_table(self, table: DatabaseTable) -> DatabaseTable: """Create a Database Table. Useful for registering pre-existing PG tables in UC. See CreateSyncedDatabaseTable for creating synced tables in PG from a source table in UC. :param table: :class:`DatabaseTable` :returns: :class:`DatabaseTable` """ body = table.as_dict() headers = { "Accept": "application/json", "Content-Type": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id res = self._api.do("POST", "/api/2.0/database/tables", body=body, headers=headers) return DatabaseTable.from_dict(res) def create_synced_database_table(self, synced_table: SyncedDatabaseTable) -> SyncedDatabaseTable: """Create a Synced Database Table. :param synced_table: :class:`SyncedDatabaseTable` :returns: :class:`SyncedDatabaseTable` """ body = synced_table.as_dict() headers = { "Accept": "application/json", "Content-Type": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id res = self._api.do("POST", "/api/2.0/database/synced_tables", body=body, headers=headers) return SyncedDatabaseTable.from_dict(res) def delete_database_catalog(self, name: str): """Delete a Database Catalog. :param name: str """ headers = { "Accept": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id self._api.do("DELETE", f"/api/2.0/database/catalogs/{name}", headers=headers) def delete_database_instance(self, name: str, *, force: Optional[bool] = None, purge: Optional[bool] = None): """Delete a Database Instance. :param name: str Name of the instance to delete. :param force: bool (optional) By default, a instance cannot be deleted if it has descendant instances created via PITR. If this flag is specified as true, all descendent instances will be deleted as well. :param purge: bool (optional) Deprecated. Omitting the field or setting it to true will result in the field being hard deleted. Setting a value of false will throw a bad request. """ query = {} if force is not None: query["force"] = force if purge is not None: query["purge"] = purge headers = { "Accept": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id self._api.do("DELETE", f"/api/2.0/database/instances/{name}", query=query, headers=headers) def delete_database_instance_role( self, instance_name: str, name: str, *, allow_missing: Optional[bool] = None, reassign_owned_to: Optional[str] = None, ): """Deletes a role for a Database Instance. :param instance_name: str :param name: str :param allow_missing: bool (optional) This is the AIP standard name for the equivalent of Postgres' `IF EXISTS` option :param reassign_owned_to: str (optional) """ query = {} if allow_missing is not None: query["allow_missing"] = allow_missing if reassign_owned_to is not None: query["reassign_owned_to"] = reassign_owned_to headers = { "Accept": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id self._api.do( "DELETE", f"/api/2.0/database/instances/{instance_name}/roles/{name}", query=query, headers=headers ) def delete_database_table(self, name: str): """Delete a Database Table. :param name: str """ headers = { "Accept": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id self._api.do("DELETE", f"/api/2.0/database/tables/{name}", headers=headers) def delete_synced_database_table(self, name: str, *, purge_data: Optional[bool] = None): """Delete a Synced Database Table. :param name: str :param purge_data: bool (optional) Optional. When set to true, the actual PostgreSQL table will be dropped from the database. """ query = {} if purge_data is not None: query["purge_data"] = purge_data headers = { "Accept": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id self._api.do("DELETE", f"/api/2.0/database/synced_tables/{name}", query=query, headers=headers) def find_database_instance_by_uid(self, *, uid: Optional[str] = None) -> DatabaseInstance: """Find a Database Instance by uid. :param uid: str (optional) UID of the cluster to get. :returns: :class:`DatabaseInstance` """ query = {} if uid is not None: query["uid"] = uid headers = { "Accept": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id res = self._api.do("GET", "/api/2.0/database/instances:findByUid", query=query, headers=headers) return DatabaseInstance.from_dict(res) def generate_database_credential( self, *, claims: Optional[List[RequestedClaims]] = None, instance_names: Optional[List[str]] = None, request_id: Optional[str] = None, ) -> DatabaseCredential: """Generates a credential that can be used to access database instances. :param claims: List[:class:`RequestedClaims`] (optional) The returned token will be scoped to the union of instance_names and instances containing the specified UC tables, so instance_names is allowed to be empty. :param instance_names: List[str] (optional) Instances to which the token will be scoped. :param request_id: str (optional) :returns: :class:`DatabaseCredential` """ if request_id is None or request_id == "": request_id = str(uuid.uuid4()) body = {} if claims is not None: body["claims"] = [v.as_dict() for v in claims] if instance_names is not None: body["instance_names"] = [v for v in instance_names] if request_id is not None: body["request_id"] = request_id headers = { "Accept": "application/json", "Content-Type": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id res = self._api.do("POST", "/api/2.0/database/credentials", body=body, headers=headers) return DatabaseCredential.from_dict(res) def get_database_catalog(self, name: str) -> DatabaseCatalog: """Get a Database Catalog. :param name: str :returns: :class:`DatabaseCatalog` """ headers = { "Accept": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id res = self._api.do("GET", f"/api/2.0/database/catalogs/{name}", headers=headers) return DatabaseCatalog.from_dict(res) def get_database_instance(self, name: str) -> DatabaseInstance: """Get a Database Instance. :param name: str Name of the cluster to get. :returns: :class:`DatabaseInstance` """ headers = { "Accept": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id res = self._api.do("GET", f"/api/2.0/database/instances/{name}", headers=headers) return DatabaseInstance.from_dict(res) def get_database_instance_role(self, instance_name: str, name: str) -> DatabaseInstanceRole: """Gets a role for a Database Instance. :param instance_name: str :param name: str :returns: :class:`DatabaseInstanceRole` """ headers = { "Accept": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id res = self._api.do("GET", f"/api/2.0/database/instances/{instance_name}/roles/{name}", headers=headers) return DatabaseInstanceRole.from_dict(res) def get_database_table(self, name: str) -> DatabaseTable: """Get a Database Table. :param name: str :returns: :class:`DatabaseTable` """ headers = { "Accept": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id res = self._api.do("GET", f"/api/2.0/database/tables/{name}", headers=headers) return DatabaseTable.from_dict(res) def get_synced_database_table(self, name: str) -> SyncedDatabaseTable: """Get a Synced Database Table. :param name: str :returns: :class:`SyncedDatabaseTable` """ headers = { "Accept": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id res = self._api.do("GET", f"/api/2.0/database/synced_tables/{name}", headers=headers) return SyncedDatabaseTable.from_dict(res) def list_database_catalogs( self, instance_name: str, *, page_size: Optional[int] = None, page_token: Optional[str] = None ) -> Iterator[DatabaseCatalog]: """This API is currently unimplemented, but exposed for Terraform support. :param instance_name: str Name of the instance to get database catalogs for. :param page_size: int (optional) Upper bound for items returned. :param page_token: str (optional) Pagination token to go to the next page of synced database tables. Requests first page if absent. :returns: Iterator over :class:`DatabaseCatalog` """ query = {} if page_size is not None: query["page_size"] = page_size if page_token is not None: query["page_token"] = page_token headers = { "Accept": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id while True: json = self._api.do( "GET", f"/api/2.0/database/instances/{instance_name}/catalogs", query=query, headers=headers ) if "database_catalogs" in json: for v in json["database_catalogs"]: yield DatabaseCatalog.from_dict(v) if "next_page_token" not in json or not json["next_page_token"]: return query["page_token"] = json["next_page_token"] def list_database_instance_roles( self, instance_name: str, *, page_size: Optional[int] = None, page_token: Optional[str] = None ) -> Iterator[DatabaseInstanceRole]: """START OF PG ROLE APIs Section These APIs are marked a PUBLIC with stage < PUBLIC_PREVIEW. With more recent Lakebase V2 plans, we don't plan to ever advance these to PUBLIC_PREVIEW. These APIs will remain effectively undocumented/UI-only and we'll aim for a new public roles API as part of V2 PuPr. :param instance_name: str :param page_size: int (optional) Upper bound for items returned. :param page_token: str (optional) Pagination token to go to the next page of Database Instances. Requests first page if absent. :returns: Iterator over :class:`DatabaseInstanceRole` """ query = {} if page_size is not None: query["page_size"] = page_size if page_token is not None: query["page_token"] = page_token headers = { "Accept": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id while True: json = self._api.do( "GET", f"/api/2.0/database/instances/{instance_name}/roles", query=query, headers=headers ) if "database_instance_roles" in json: for v in json["database_instance_roles"]: yield DatabaseInstanceRole.from_dict(v) if "next_page_token" not in json or not json["next_page_token"]: return query["page_token"] = json["next_page_token"] def list_database_instances( self, *, page_size: Optional[int] = None, page_token: Optional[str] = None ) -> Iterator[DatabaseInstance]: """List Database Instances. :param page_size: int (optional) Upper bound for items returned. The maximum value is 100. :param page_token: str (optional) Pagination token to go to the next page of Database Instances. Requests first page if absent. :returns: Iterator over :class:`DatabaseInstance` """ query = {} if page_size is not None: query["page_size"] = page_size if page_token is not None: query["page_token"] = page_token headers = { "Accept": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id while True: json = self._api.do("GET", "/api/2.0/database/instances", query=query, headers=headers) if "database_instances" in json: for v in json["database_instances"]: yield DatabaseInstance.from_dict(v) if "next_page_token" not in json or not json["next_page_token"]: return query["page_token"] = json["next_page_token"] def list_synced_database_tables( self, instance_name: str, *, page_size: Optional[int] = None, page_token: Optional[str] = None ) -> Iterator[SyncedDatabaseTable]: """This API is currently unimplemented, but exposed for Terraform support. :param instance_name: str Name of the instance to get synced tables for. :param page_size: int (optional) Upper bound for items returned. :param page_token: str (optional) Pagination token to go to the next page of synced database tables. Requests first page if absent. :returns: Iterator over :class:`SyncedDatabaseTable` """ query = {} if page_size is not None: query["page_size"] = page_size if page_token is not None: query["page_token"] = page_token headers = { "Accept": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id while True: json = self._api.do( "GET", f"/api/2.0/database/instances/{instance_name}/synced_tables", query=query, headers=headers ) if "synced_tables" in json: for v in json["synced_tables"]: yield SyncedDatabaseTable.from_dict(v) if "next_page_token" not in json or not json["next_page_token"]: return query["page_token"] = json["next_page_token"] def update_database_catalog( self, name: str, database_catalog: DatabaseCatalog, update_mask: str ) -> DatabaseCatalog: """This API is currently unimplemented, but exposed for Terraform support. :param name: str The name of the catalog in UC. :param database_catalog: :class:`DatabaseCatalog` Note that updating a database catalog is not yet supported. :param update_mask: str The list of fields to update. Setting this field is not yet supported. :returns: :class:`DatabaseCatalog` """ body = database_catalog.as_dict() query = {} if update_mask is not None: query["update_mask"] = update_mask headers = { "Accept": "application/json", "Content-Type": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id res = self._api.do("PATCH", f"/api/2.0/database/catalogs/{name}", query=query, body=body, headers=headers) return DatabaseCatalog.from_dict(res) def update_database_instance( self, name: str, database_instance: DatabaseInstance, update_mask: str ) -> DatabaseInstance: """Update a Database Instance. :param name: str The name of the instance. This is the unique identifier for the instance. :param database_instance: :class:`DatabaseInstance` :param update_mask: str The list of fields to update. If unspecified, all fields will be updated when possible. To wipe out custom_tags, specify custom_tags in the update_mask with an empty custom_tags map. :returns: :class:`DatabaseInstance` """ body = database_instance.as_dict() query = {} if update_mask is not None: query["update_mask"] = update_mask headers = { "Accept": "application/json", "Content-Type": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id res = self._api.do("PATCH", f"/api/2.0/database/instances/{name}", query=query, body=body, headers=headers) return DatabaseInstance.from_dict(res) def update_synced_database_table( self, name: str, synced_table: SyncedDatabaseTable, update_mask: str ) -> SyncedDatabaseTable: """This API is currently unimplemented, but exposed for Terraform support. :param name: str Full three-part (catalog, schema, table) name of the table. :param synced_table: :class:`SyncedDatabaseTable` Note that updating a synced database table is not yet supported. :param update_mask: str The list of fields to update. Setting this field is not yet supported. :returns: :class:`SyncedDatabaseTable` """ body = synced_table.as_dict() query = {} if update_mask is not None: query["update_mask"] = update_mask headers = { "Accept": "application/json", "Content-Type": "application/json", } cfg = self._api._cfg if cfg.host_type == HostType.UNIFIED and cfg.workspace_id: headers["X-Databricks-Org-Id"] = cfg.workspace_id res = self._api.do("PATCH", f"/api/2.0/database/synced_tables/{name}", query=query, body=body, headers=headers) return SyncedDatabaseTable.from_dict(res)