Files
zenml/venv/lib/python3.9/site-packages/databricks/sdk/service/database.py
Christian Mantha 2ca0b9ef7c star
2026-03-02 19:10:52 -05:00

2262 lines
94 KiB
Python

# 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)