diff --git a/CHANGELOG.md b/CHANGELOG.md index addc5b2..23b1288 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- feat(schemas): add key field to table definitions - feat(tables): support loading from query results ## [0.6.0] - 2026-07-07 diff --git a/docs/AddManagedTableDecl.md b/docs/AddManagedTableDecl.md index 1fb68f1..f3be755 100644 --- a/docs/AddManagedTableDecl.md +++ b/docs/AddManagedTableDecl.md @@ -6,6 +6,7 @@ One table declaration inside an add-schema request body. Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**key** | **List[str]** | Columns that uniquely identify a row, enabling the key-based load modes (`delete`, `update`, `upsert`) on this table: those loads match rows by these columns' values. Omit (the default) to declare no key; the table can still be loaded with `replace` and `append`, but key-based modes are then rejected. | [optional] **name** | **str** | | ## Example diff --git a/docs/AddManagedTableRequest.md b/docs/AddManagedTableRequest.md index f4f8f64..19b7439 100644 --- a/docs/AddManagedTableRequest.md +++ b/docs/AddManagedTableRequest.md @@ -6,6 +6,7 @@ Request body for adding a table to an existing schema: `POST /v1/connections/{id Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**key** | **List[str]** | Columns that uniquely identify a row, enabling the key-based load modes (`delete`, `update`, `upsert`) on this table: those loads match rows by these columns' values. Omit (the default) to declare no key; the table can still be loaded with `replace` and `append`, but key-based modes are then rejected. | [optional] **name** | **str** | | ## Example diff --git a/docs/DatabaseDefaultTableDecl.md b/docs/DatabaseDefaultTableDecl.md index 13b8dc9..69e02b9 100644 --- a/docs/DatabaseDefaultTableDecl.md +++ b/docs/DatabaseDefaultTableDecl.md @@ -6,6 +6,7 @@ One table declaration inside a default-catalog schema, supplied at database-crea Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**key** | **List[str]** | Columns that uniquely identify a row, enabling the key-based load modes (`delete`, `update`, `upsert`) on this table: those loads match rows by these columns' values. Omit (the default) to declare no key; the table can still be loaded with `replace` and `append`, but key-based modes are then rejected. | [optional] **name** | **str** | | ## Example diff --git a/hotdata/models/add_managed_table_decl.py b/hotdata/models/add_managed_table_decl.py index 99ea7dc..2edf1f5 100644 --- a/hotdata/models/add_managed_table_decl.py +++ b/hotdata/models/add_managed_table_decl.py @@ -18,8 +18,8 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictStr -from typing import Any, ClassVar, Dict, List +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 @@ -27,8 +27,9 @@ class AddManagedTableDecl(BaseModel): """ One table declaration inside an add-schema request body. """ # noqa: E501 + key: Optional[List[StrictStr]] = Field(default=None, description="Columns that uniquely identify a row, enabling the key-based load modes (`delete`, `update`, `upsert`) on this table: those loads match rows by these columns' values. Omit (the default) to declare no key; the table can still be loaded with `replace` and `append`, but key-based modes are then rejected.") name: StrictStr - __properties: ClassVar[List[str]] = ["name"] + __properties: ClassVar[List[str]] = ["key", "name"] model_config = ConfigDict( populate_by_name=True, @@ -81,6 +82,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: return cls.model_validate(obj) _obj = cls.model_validate({ + "key": obj.get("key"), "name": obj.get("name") }) return _obj diff --git a/hotdata/models/add_managed_table_request.py b/hotdata/models/add_managed_table_request.py index c232785..60af826 100644 --- a/hotdata/models/add_managed_table_request.py +++ b/hotdata/models/add_managed_table_request.py @@ -18,8 +18,8 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictStr -from typing import Any, ClassVar, Dict, List +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 @@ -27,8 +27,9 @@ class AddManagedTableRequest(BaseModel): """ Request body for adding a table to an existing schema: `POST /v1/connections/{id}/schemas/{schema}/tables` and `POST /v1/databases/{id}/schemas/{schema}/tables`. """ # noqa: E501 + key: Optional[List[StrictStr]] = Field(default=None, description="Columns that uniquely identify a row, enabling the key-based load modes (`delete`, `update`, `upsert`) on this table: those loads match rows by these columns' values. Omit (the default) to declare no key; the table can still be loaded with `replace` and `append`, but key-based modes are then rejected.") name: StrictStr - __properties: ClassVar[List[str]] = ["name"] + __properties: ClassVar[List[str]] = ["key", "name"] model_config = ConfigDict( populate_by_name=True, @@ -81,6 +82,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: return cls.model_validate(obj) _obj = cls.model_validate({ + "key": obj.get("key"), "name": obj.get("name") }) return _obj diff --git a/hotdata/models/database_default_table_decl.py b/hotdata/models/database_default_table_decl.py index 9a9729a..32506ab 100644 --- a/hotdata/models/database_default_table_decl.py +++ b/hotdata/models/database_default_table_decl.py @@ -18,8 +18,8 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictStr -from typing import Any, ClassVar, Dict, List +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 @@ -27,8 +27,9 @@ class DatabaseDefaultTableDecl(BaseModel): """ One table declaration inside a default-catalog schema, supplied at database-create time. """ # noqa: E501 + key: Optional[List[StrictStr]] = Field(default=None, description="Columns that uniquely identify a row, enabling the key-based load modes (`delete`, `update`, `upsert`) on this table: those loads match rows by these columns' values. Omit (the default) to declare no key; the table can still be loaded with `replace` and `append`, but key-based modes are then rejected.") name: StrictStr - __properties: ClassVar[List[str]] = ["name"] + __properties: ClassVar[List[str]] = ["key", "name"] model_config = ConfigDict( populate_by_name=True, @@ -81,6 +82,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: return cls.model_validate(obj) _obj = cls.model_validate({ + "key": obj.get("key"), "name": obj.get("name") }) return _obj diff --git a/test/test_add_managed_schema_request.py b/test/test_add_managed_schema_request.py index 0c579a9..eab9b9a 100644 --- a/test/test_add_managed_schema_request.py +++ b/test/test_add_managed_schema_request.py @@ -39,6 +39,9 @@ def make_instance(self, include_optional) -> AddManagedSchemaRequest: name = '', tables = [ hotdata.models.add_managed_table_decl.AddManagedTableDecl( + key = [ + '' + ], name = '', ) ] ) diff --git a/test/test_add_managed_table_decl.py b/test/test_add_managed_table_decl.py index 5cbe31d..3d86b9c 100644 --- a/test/test_add_managed_table_decl.py +++ b/test/test_add_managed_table_decl.py @@ -36,6 +36,9 @@ def make_instance(self, include_optional) -> AddManagedTableDecl: model = AddManagedTableDecl() if include_optional: return AddManagedTableDecl( + key = [ + '' + ], name = '' ) else: diff --git a/test/test_add_managed_table_request.py b/test/test_add_managed_table_request.py index 9c1f172..a2e6dcc 100644 --- a/test/test_add_managed_table_request.py +++ b/test/test_add_managed_table_request.py @@ -36,6 +36,9 @@ def make_instance(self, include_optional) -> AddManagedTableRequest: model = AddManagedTableRequest() if include_optional: return AddManagedTableRequest( + key = [ + '' + ], name = '' ) else: diff --git a/test/test_create_database_request.py b/test/test_create_database_request.py index 58a9ef0..eba7a5c 100644 --- a/test/test_create_database_request.py +++ b/test/test_create_database_request.py @@ -44,6 +44,9 @@ def make_instance(self, include_optional) -> CreateDatabaseRequest: name = '', tables = [ hotdata.models.database_default_table_decl.DatabaseDefaultTableDecl( + key = [ + '' + ], name = '', ) ], ) ] diff --git a/test/test_database_default_schema_decl.py b/test/test_database_default_schema_decl.py index de89f06..9f71bd4 100644 --- a/test/test_database_default_schema_decl.py +++ b/test/test_database_default_schema_decl.py @@ -39,6 +39,9 @@ def make_instance(self, include_optional) -> DatabaseDefaultSchemaDecl: name = '', tables = [ hotdata.models.database_default_table_decl.DatabaseDefaultTableDecl( + key = [ + '' + ], name = '', ) ] ) diff --git a/test/test_database_default_table_decl.py b/test/test_database_default_table_decl.py index 2b5d6ba..91b6501 100644 --- a/test/test_database_default_table_decl.py +++ b/test/test_database_default_table_decl.py @@ -36,6 +36,9 @@ def make_instance(self, include_optional) -> DatabaseDefaultTableDecl: model = DatabaseDefaultTableDecl() if include_optional: return DatabaseDefaultTableDecl( + key = [ + '' + ], name = '' ) else: