diff --git a/docs/CreateDatabaseRequest.md b/docs/CreateDatabaseRequest.md index cd8c89b..4afafec 100644 --- a/docs/CreateDatabaseRequest.md +++ b/docs/CreateDatabaseRequest.md @@ -6,9 +6,10 @@ Request body for POST /databases Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**default_catalog** | **str** | Optional name the database's auto-created default catalog answers to inside its query scope. Must be a valid SQL identifier (`[a-z0-9_]`, not starting with a digit) and may not collide with the system catalogs `hotdata`, `datasets`, or `information_schema`. Defaults to `default` when omitted, so `default.main.<table>` keeps working. | [optional] **expires_at** | **str** | When this database expires. Accepts either an RFC 3339 timestamp (e.g. `\"2026-06-01T00:00:00Z\"`) or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days) — for example `\"24h\"`, `\"48h\"`, or `\"7d\"`. Omitted (or empty) means the database never expires. Expiry is best-effort: the database will not be deleted before `expires_at`, but cleanup may run later than the exact timestamp. | [optional] **name** | **str** | Optional free-form display label (for UIs/CLIs). Not unique. Not an identifier — databases are always addressed by `id`. Accepts the legacy `description` key as an alias so clients that predate the rename keep populating this field. | [optional] -**schemas** | [**List[DatabaseDefaultSchemaDecl]**](DatabaseDefaultSchemaDecl.md) | Optional schemas/tables to declare on the database's auto-created `default` catalog. Mirrors the `config.schemas` field of a managed `POST /v1/connections`. Tables declared here can be loaded via the standard managed-table load endpoint targeting `default_connection_id`. Omitted or empty means the default catalog starts empty. | [optional] +**schemas** | [**List[DatabaseDefaultSchemaDecl]**](DatabaseDefaultSchemaDecl.md) | Optional schemas/tables to declare on the database's auto-created default catalog. Mirrors the `config.schemas` field of a managed `POST /v1/connections`. Tables declared here can be loaded via the standard managed-table load endpoint targeting `default_connection_id`. Omitted or empty means the default catalog starts empty. | [optional] **storage_backend** | **str** | Physical storage backend for the database's auto-created `default` catalog. `\"parquet\"` (default) uses the versioned parquet cache. `\"ducklake\"` stores data in a DuckLake catalog in the shared metadata DB configured via `ducklake.metadata_pg_url`, which must be configured for that value to be accepted. Omitted means `\"parquet\"`. | [optional] ## Example diff --git a/docs/CreateDatabaseResponse.md b/docs/CreateDatabaseResponse.md index 6c4062a..536727c 100644 --- a/docs/CreateDatabaseResponse.md +++ b/docs/CreateDatabaseResponse.md @@ -6,6 +6,7 @@ Response body for POST /databases Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**default_catalog** | **str** | Name the database's default catalog answers to inside its query scope (`default` unless overridden at create time). | **default_connection_id** | **str** | Internal id of the connection that backs this database's `default` catalog. Workspace-level connection endpoints (list, get, health, delete, cache purge) refuse to act on this id — it is exposed only for the managed-tables load endpoint (`POST /v1/connections/{id}/schemas/{s}/tables/{t}/loads`) so callers can publish parquet into tables declared at database-create time. Addressing it directly in SQL is not the recommended path — use `default` inside an `X-Database-Id` scope instead. | **expires_at** | **datetime** | When this database expires. | [optional] **id** | **str** | | diff --git a/docs/DatabaseDetailResponse.md b/docs/DatabaseDetailResponse.md index 2de9bd5..7e7e3fb 100644 --- a/docs/DatabaseDetailResponse.md +++ b/docs/DatabaseDetailResponse.md @@ -7,6 +7,7 @@ Response body for GET /databases/{database_id} Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **attachments** | [**List[DatabaseAttachmentInfo]**](DatabaseAttachmentInfo.md) | | +**default_catalog** | **str** | Name the database's default catalog answers to inside its query scope (`default` unless overridden at create time). | **default_connection_id** | **str** | | **expires_at** | **datetime** | When this database expires. | [optional] **id** | **str** | | diff --git a/docs/DatabaseSummary.md b/docs/DatabaseSummary.md index 3fc1247..83784a5 100644 --- a/docs/DatabaseSummary.md +++ b/docs/DatabaseSummary.md @@ -6,6 +6,7 @@ Summary item in GET /databases Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**default_catalog** | **str** | Name the database's default catalog answers to inside its query scope. | **expires_at** | **datetime** | | [optional] **id** | **str** | | **name** | **str** | | [optional] diff --git a/docs/DatabasesApi.md b/docs/DatabasesApi.md index b141f59..d108cfc 100644 --- a/docs/DatabasesApi.md +++ b/docs/DatabasesApi.md @@ -105,7 +105,7 @@ void (empty response body) Create database -Create a new database (a metadata-only grouping). A managed default catalog is auto-created and addressable inside the database as `default`, with a `main` schema pre-declared so `default.main.` works out of the box. The optional `name` is a free-form display label and is not required to be unique. Optional `schemas` declares additional schemas/tables on the default catalog at create time; declared tables can be loaded via the standard managed-tables-load endpoint targeting `default_connection_id`. Optional `expires_at` sets when the database expires — accepts either an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `48h`, `90m`, `7d`. When omitted, the database never expires. Expiry is best-effort: the database will not be deleted before `expires_at`, but cleanup may run later than the exact timestamp. Optional `storage_backend` selects the physical backend for the default catalog — `parquet` (default) or `ducklake` (requires `ducklake.metadata_pg_url` to be configured). +Create a new database (a metadata-only grouping). A managed default catalog is auto-created and addressable inside the database as `default` (or the optional `default_catalog` name), with a `main` schema pre-declared so `default.main.
` works out of the box. The optional `name` is a free-form display label and is not required to be unique. Optional `default_catalog` overrides the name the default catalog answers to; it must be a valid SQL identifier and may not collide with the `hotdata`, `datasets`, or `information_schema` system catalogs. Optional `schemas` declares additional schemas/tables on the default catalog at create time; declared tables can be loaded via the standard managed-tables-load endpoint targeting `default_connection_id`. Optional `expires_at` sets when the database expires — accepts either an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `48h`, `90m`, `7d`. When omitted, the database never expires. Expiry is best-effort: the database will not be deleted before `expires_at`, but cleanup may run later than the exact timestamp. Optional `storage_backend` selects the physical backend for the default catalog — `parquet` (default) or `ducklake` (requires `ducklake.metadata_pg_url` to be configured). ### Example diff --git a/hotdata/api/databases_api.py b/hotdata/api/databases_api.py index fc316de..02726d6 100644 --- a/hotdata/api/databases_api.py +++ b/hotdata/api/databases_api.py @@ -360,7 +360,7 @@ def create_database( ) -> CreateDatabaseResponse: """Create database - Create a new database (a metadata-only grouping). A managed default catalog is auto-created and addressable inside the database as `default`, with a `main` schema pre-declared so `default.main.
` works out of the box. The optional `name` is a free-form display label and is not required to be unique. Optional `schemas` declares additional schemas/tables on the default catalog at create time; declared tables can be loaded via the standard managed-tables-load endpoint targeting `default_connection_id`. Optional `expires_at` sets when the database expires — accepts either an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `48h`, `90m`, `7d`. When omitted, the database never expires. Expiry is best-effort: the database will not be deleted before `expires_at`, but cleanup may run later than the exact timestamp. Optional `storage_backend` selects the physical backend for the default catalog — `parquet` (default) or `ducklake` (requires `ducklake.metadata_pg_url` to be configured). + Create a new database (a metadata-only grouping). A managed default catalog is auto-created and addressable inside the database as `default` (or the optional `default_catalog` name), with a `main` schema pre-declared so `default.main.
` works out of the box. The optional `name` is a free-form display label and is not required to be unique. Optional `default_catalog` overrides the name the default catalog answers to; it must be a valid SQL identifier and may not collide with the `hotdata`, `datasets`, or `information_schema` system catalogs. Optional `schemas` declares additional schemas/tables on the default catalog at create time; declared tables can be loaded via the standard managed-tables-load endpoint targeting `default_connection_id`. Optional `expires_at` sets when the database expires — accepts either an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `48h`, `90m`, `7d`. When omitted, the database never expires. Expiry is best-effort: the database will not be deleted before `expires_at`, but cleanup may run later than the exact timestamp. Optional `storage_backend` selects the physical backend for the default catalog — `parquet` (default) or `ducklake` (requires `ducklake.metadata_pg_url` to be configured). :param create_database_request: (required) :type create_database_request: CreateDatabaseRequest @@ -429,7 +429,7 @@ def create_database_with_http_info( ) -> ApiResponse[CreateDatabaseResponse]: """Create database - Create a new database (a metadata-only grouping). A managed default catalog is auto-created and addressable inside the database as `default`, with a `main` schema pre-declared so `default.main.
` works out of the box. The optional `name` is a free-form display label and is not required to be unique. Optional `schemas` declares additional schemas/tables on the default catalog at create time; declared tables can be loaded via the standard managed-tables-load endpoint targeting `default_connection_id`. Optional `expires_at` sets when the database expires — accepts either an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `48h`, `90m`, `7d`. When omitted, the database never expires. Expiry is best-effort: the database will not be deleted before `expires_at`, but cleanup may run later than the exact timestamp. Optional `storage_backend` selects the physical backend for the default catalog — `parquet` (default) or `ducklake` (requires `ducklake.metadata_pg_url` to be configured). + Create a new database (a metadata-only grouping). A managed default catalog is auto-created and addressable inside the database as `default` (or the optional `default_catalog` name), with a `main` schema pre-declared so `default.main.
` works out of the box. The optional `name` is a free-form display label and is not required to be unique. Optional `default_catalog` overrides the name the default catalog answers to; it must be a valid SQL identifier and may not collide with the `hotdata`, `datasets`, or `information_schema` system catalogs. Optional `schemas` declares additional schemas/tables on the default catalog at create time; declared tables can be loaded via the standard managed-tables-load endpoint targeting `default_connection_id`. Optional `expires_at` sets when the database expires — accepts either an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `48h`, `90m`, `7d`. When omitted, the database never expires. Expiry is best-effort: the database will not be deleted before `expires_at`, but cleanup may run later than the exact timestamp. Optional `storage_backend` selects the physical backend for the default catalog — `parquet` (default) or `ducklake` (requires `ducklake.metadata_pg_url` to be configured). :param create_database_request: (required) :type create_database_request: CreateDatabaseRequest @@ -498,7 +498,7 @@ def create_database_without_preload_content( ) -> RESTResponseType: """Create database - Create a new database (a metadata-only grouping). A managed default catalog is auto-created and addressable inside the database as `default`, with a `main` schema pre-declared so `default.main.
` works out of the box. The optional `name` is a free-form display label and is not required to be unique. Optional `schemas` declares additional schemas/tables on the default catalog at create time; declared tables can be loaded via the standard managed-tables-load endpoint targeting `default_connection_id`. Optional `expires_at` sets when the database expires — accepts either an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `48h`, `90m`, `7d`. When omitted, the database never expires. Expiry is best-effort: the database will not be deleted before `expires_at`, but cleanup may run later than the exact timestamp. Optional `storage_backend` selects the physical backend for the default catalog — `parquet` (default) or `ducklake` (requires `ducklake.metadata_pg_url` to be configured). + Create a new database (a metadata-only grouping). A managed default catalog is auto-created and addressable inside the database as `default` (or the optional `default_catalog` name), with a `main` schema pre-declared so `default.main.
` works out of the box. The optional `name` is a free-form display label and is not required to be unique. Optional `default_catalog` overrides the name the default catalog answers to; it must be a valid SQL identifier and may not collide with the `hotdata`, `datasets`, or `information_schema` system catalogs. Optional `schemas` declares additional schemas/tables on the default catalog at create time; declared tables can be loaded via the standard managed-tables-load endpoint targeting `default_connection_id`. Optional `expires_at` sets when the database expires — accepts either an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `48h`, `90m`, `7d`. When omitted, the database never expires. Expiry is best-effort: the database will not be deleted before `expires_at`, but cleanup may run later than the exact timestamp. Optional `storage_backend` selects the physical backend for the default catalog — `parquet` (default) or `ducklake` (requires `ducklake.metadata_pg_url` to be configured). :param create_database_request: (required) :type create_database_request: CreateDatabaseRequest diff --git a/hotdata/models/create_database_request.py b/hotdata/models/create_database_request.py index 51a8ed8..ed64625 100644 --- a/hotdata/models/create_database_request.py +++ b/hotdata/models/create_database_request.py @@ -28,11 +28,12 @@ class CreateDatabaseRequest(BaseModel): """ Request body for POST /databases """ # noqa: E501 + default_catalog: Optional[StrictStr] = Field(default=None, description="Optional name the database's auto-created default catalog answers to inside its query scope. Must be a valid SQL identifier (`[a-z0-9_]`, not starting with a digit) and may not collide with the system catalogs `hotdata`, `datasets`, or `information_schema`. Defaults to `default` when omitted, so `default.main.
` keeps working.") expires_at: Optional[StrictStr] = Field(default=None, description="When this database expires. Accepts either an RFC 3339 timestamp (e.g. `\"2026-06-01T00:00:00Z\"`) or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days) — for example `\"24h\"`, `\"48h\"`, or `\"7d\"`. Omitted (or empty) means the database never expires. Expiry is best-effort: the database will not be deleted before `expires_at`, but cleanup may run later than the exact timestamp.") name: Optional[StrictStr] = Field(default=None, description="Optional free-form display label (for UIs/CLIs). Not unique. Not an identifier — databases are always addressed by `id`. Accepts the legacy `description` key as an alias so clients that predate the rename keep populating this field.") - schemas: Optional[List[DatabaseDefaultSchemaDecl]] = Field(default=None, description="Optional schemas/tables to declare on the database's auto-created `default` catalog. Mirrors the `config.schemas` field of a managed `POST /v1/connections`. Tables declared here can be loaded via the standard managed-table load endpoint targeting `default_connection_id`. Omitted or empty means the default catalog starts empty.") + schemas: Optional[List[DatabaseDefaultSchemaDecl]] = Field(default=None, description="Optional schemas/tables to declare on the database's auto-created default catalog. Mirrors the `config.schemas` field of a managed `POST /v1/connections`. Tables declared here can be loaded via the standard managed-table load endpoint targeting `default_connection_id`. Omitted or empty means the default catalog starts empty.") storage_backend: Optional[StrictStr] = Field(default=None, description="Physical storage backend for the database's auto-created `default` catalog. `\"parquet\"` (default) uses the versioned parquet cache. `\"ducklake\"` stores data in a DuckLake catalog in the shared metadata DB configured via `ducklake.metadata_pg_url`, which must be configured for that value to be accepted. Omitted means `\"parquet\"`.") - __properties: ClassVar[List[str]] = ["expires_at", "name", "schemas", "storage_backend"] + __properties: ClassVar[List[str]] = ["default_catalog", "expires_at", "name", "schemas", "storage_backend"] model_config = ConfigDict( populate_by_name=True, @@ -80,6 +81,11 @@ def to_dict(self) -> Dict[str, Any]: if _item_schemas: _items.append(_item_schemas.to_dict()) _dict['schemas'] = _items + # set to None if default_catalog (nullable) is None + # and model_fields_set contains the field + if self.default_catalog is None and "default_catalog" in self.model_fields_set: + _dict['default_catalog'] = None + # set to None if expires_at (nullable) is None # and model_fields_set contains the field if self.expires_at is None and "expires_at" in self.model_fields_set: @@ -107,6 +113,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: return cls.model_validate(obj) _obj = cls.model_validate({ + "default_catalog": obj.get("default_catalog"), "expires_at": obj.get("expires_at"), "name": obj.get("name"), "schemas": [DatabaseDefaultSchemaDecl.from_dict(_item) for _item in obj["schemas"]] if obj.get("schemas") is not None else None, diff --git a/hotdata/models/create_database_response.py b/hotdata/models/create_database_response.py index 84bf231..b43dca1 100644 --- a/hotdata/models/create_database_response.py +++ b/hotdata/models/create_database_response.py @@ -28,11 +28,12 @@ class CreateDatabaseResponse(BaseModel): """ Response body for POST /databases """ # noqa: E501 + default_catalog: StrictStr = Field(description="Name the database's default catalog answers to inside its query scope (`default` unless overridden at create time).") default_connection_id: StrictStr = Field(description="Internal id of the connection that backs this database's `default` catalog. Workspace-level connection endpoints (list, get, health, delete, cache purge) refuse to act on this id — it is exposed only for the managed-tables load endpoint (`POST /v1/connections/{id}/schemas/{s}/tables/{t}/loads`) so callers can publish parquet into tables declared at database-create time. Addressing it directly in SQL is not the recommended path — use `default` inside an `X-Database-Id` scope instead.") expires_at: Optional[datetime] = Field(default=None, description="When this database expires.") id: StrictStr name: Optional[StrictStr] = None - __properties: ClassVar[List[str]] = ["default_connection_id", "expires_at", "id", "name"] + __properties: ClassVar[List[str]] = ["default_catalog", "default_connection_id", "expires_at", "id", "name"] model_config = ConfigDict( populate_by_name=True, @@ -95,6 +96,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: return cls.model_validate(obj) _obj = cls.model_validate({ + "default_catalog": obj.get("default_catalog"), "default_connection_id": obj.get("default_connection_id"), "expires_at": obj.get("expires_at"), "id": obj.get("id"), diff --git a/hotdata/models/database_detail_response.py b/hotdata/models/database_detail_response.py index e403ae4..c82c7b6 100644 --- a/hotdata/models/database_detail_response.py +++ b/hotdata/models/database_detail_response.py @@ -30,11 +30,12 @@ class DatabaseDetailResponse(BaseModel): Response body for GET /databases/{database_id} """ # noqa: E501 attachments: List[DatabaseAttachmentInfo] + default_catalog: StrictStr = Field(description="Name the database's default catalog answers to inside its query scope (`default` unless overridden at create time).") default_connection_id: StrictStr expires_at: Optional[datetime] = Field(default=None, description="When this database expires.") id: StrictStr name: Optional[StrictStr] = None - __properties: ClassVar[List[str]] = ["attachments", "default_connection_id", "expires_at", "id", "name"] + __properties: ClassVar[List[str]] = ["attachments", "default_catalog", "default_connection_id", "expires_at", "id", "name"] model_config = ConfigDict( populate_by_name=True, @@ -105,6 +106,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: _obj = cls.model_validate({ "attachments": [DatabaseAttachmentInfo.from_dict(_item) for _item in obj["attachments"]] if obj.get("attachments") is not None else None, + "default_catalog": obj.get("default_catalog"), "default_connection_id": obj.get("default_connection_id"), "expires_at": obj.get("expires_at"), "id": obj.get("id"), diff --git a/hotdata/models/database_summary.py b/hotdata/models/database_summary.py index 2312598..2b6453d 100644 --- a/hotdata/models/database_summary.py +++ b/hotdata/models/database_summary.py @@ -19,7 +19,7 @@ import json from datetime import datetime -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictStr from typing import Any, ClassVar, Dict, List, Optional from typing import Optional, Set from typing_extensions import Self @@ -28,10 +28,11 @@ class DatabaseSummary(BaseModel): """ Summary item in GET /databases """ # noqa: E501 + default_catalog: StrictStr = Field(description="Name the database's default catalog answers to inside its query scope.") expires_at: Optional[datetime] = None id: StrictStr name: Optional[StrictStr] = None - __properties: ClassVar[List[str]] = ["expires_at", "id", "name"] + __properties: ClassVar[List[str]] = ["default_catalog", "expires_at", "id", "name"] model_config = ConfigDict( populate_by_name=True, @@ -94,6 +95,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: return cls.model_validate(obj) _obj = cls.model_validate({ + "default_catalog": obj.get("default_catalog"), "expires_at": obj.get("expires_at"), "id": obj.get("id"), "name": obj.get("name")