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