Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ docs/SavedQuerySummary.md
docs/SavedQueryVersionInfo.md
docs/SubmitJobResponse.md
docs/TableInfo.md
docs/TableLayout.md
docs/TablePartitionKey.md
docs/TableProfileResponse.md
docs/TableSortKey.md
Expand Down Expand Up @@ -249,6 +250,7 @@ hotdata/models/saved_query_summary.py
hotdata/models/saved_query_version_info.py
hotdata/models/submit_job_response.py
hotdata/models/table_info.py
hotdata/models/table_layout.py
hotdata/models/table_partition_key.py
hotdata/models/table_profile_response.py
hotdata/models/table_sort_key.py
Expand Down Expand Up @@ -378,6 +380,7 @@ test/test_saved_query_summary.py
test/test_saved_query_version_info.py
test/test_submit_job_response.py
test/test_table_info.py
test/test_table_layout.py
test/test_table_partition_key.py
test/test_table_profile_response.py
test/test_table_sort_key.py
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- feat(tables): add layout property to table schemas
- feat(jobs): add ivf_rebalance_sweep job type
- chore(query): clarify write statement and dialect documentation
- chore: add 503 service unavailable response to load endpoints
Expand Down
1 change: 1 addition & 0 deletions docs/AddManagedTableDecl.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**constant_per_key** | **List[str]** | Columns whose value is determined by this table's `key`: for every uploaded row, every stored row sharing its key holds the same value of these columns. Declaring this lets a keyed mutation (`delete`, `update`, `upsert`) restrict its search for prior versions to the values the upload carries, which prunes far harder than the key alone when the key's own file statistics are weak. Omit (the default) for the unrestricted search. **Correctness-affecting, not a hint.** If the assertion is false, a mutation supersedes one version of a key and appends beside another, silently duplicating it. Declare it only where the invariant is established. | [optional]
**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]
**layout** | [**TableLayout**](TableLayout.md) | Storage layout of the table: `analytical` (the default), or `point_lookup`, which writes small data pages so the table's rows can be fetched by id cheaply, which is what a vector index's answers do; analytical scans of it read more pages. Declared when the table is created and fixed thereafter. | [optional]
**name** | **str** | |
**partition_by** | [**List[TablePartitionKey]**](TablePartitionKey.md) | Partition keys for this table, applied in order. Omit for no partitioning. Declared when the table is created and fixed thereafter. | [optional]
**sorted_by** | [**List[TableSortKey]**](TableSortKey.md) | Sort keys for this table, applied in order. Omit for no sort order. Declared when the table is created and fixed thereafter. A table with a sort order cannot be indexed: creating any index on it is refused, so leave this empty on a table you plan to search. | [optional]
Expand Down
1 change: 1 addition & 0 deletions docs/AddManagedTableRequest.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**constant_per_key** | **List[str]** | Columns whose value is determined by this table's `key`: for every uploaded row, every stored row sharing its key holds the same value of these columns. Declaring this lets a keyed mutation (`delete`, `update`, `upsert`) restrict its search for prior versions to the values the upload carries, which prunes far harder than the key alone when the key's own file statistics are weak. Omit (the default) for the unrestricted search. **Correctness-affecting, not a hint.** If the assertion is false, a mutation supersedes one version of a key and appends beside another, silently duplicating it. Declare it only where the invariant is established. | [optional]
**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]
**layout** | [**TableLayout**](TableLayout.md) | Storage layout of the table: `analytical` (the default), or `point_lookup`, which writes small data pages so the table's rows can be fetched by id cheaply, which is what a vector index's answers do; analytical scans of it read more pages. Declared when the table is created and fixed thereafter. | [optional]
**name** | **str** | |
**partition_by** | [**List[TablePartitionKey]**](TablePartitionKey.md) | Partition keys for this table, applied in order. Omit for no partitioning. Declared when the table is created and fixed thereafter. | [optional]
**sorted_by** | [**List[TableSortKey]**](TableSortKey.md) | Sort keys for this table, applied in order. Omit for no sort order. Declared when the table is created and fixed thereafter. A table with a sort order cannot be indexed: creating any index on it is refused, so leave this empty on a table you plan to search. | [optional]
Expand Down
1 change: 1 addition & 0 deletions docs/DatabaseDefaultTableDecl.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**constant_per_key** | **List[str]** | Columns whose value is determined by this table's `key`: for every uploaded row, every stored row sharing its key holds the same value of these columns. Declaring this lets a keyed mutation (`delete`, `update`, `upsert`) restrict its search for prior versions to the values the upload carries, which prunes far harder than the key alone when the key's own file statistics are weak. Omit (the default) for the unrestricted search. **Correctness-affecting, not a hint.** If the assertion is false, a mutation supersedes one version of a key and appends beside another, silently duplicating it. Declare it only where the invariant is established. | [optional]
**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]
**layout** | [**TableLayout**](TableLayout.md) | Storage layout of the table: `analytical` (the default), or `point_lookup`, which writes small data pages so the table's rows can be fetched by id cheaply, which is what a vector index's answers do; analytical scans of it read more pages. Declared when the table is created and fixed thereafter. | [optional]
**name** | **str** | |
**partition_by** | [**List[TablePartitionKey]**](TablePartitionKey.md) | Partition keys for this table, applied in order. Omit for no partitioning. Declared when the table is created and fixed thereafter. | [optional]
**sorted_by** | [**List[TableSortKey]**](TableSortKey.md) | Sort keys for this table, applied in order. Omit for no sort order. Declared when the table is created and fixed thereafter. A table with a sort order cannot be indexed: creating any index on it is refused, so leave this empty on a table you plan to search. | [optional]
Expand Down
1 change: 1 addition & 0 deletions docs/TableInfo.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Name | Type | Description | Notes
**connection** | **str** | |
**constant_per_key** | **List[str]** | Columns the table declares constant for a given key: for every row, any other row sharing its key holds the same value of these columns. Declaring this lets a keyed mutation narrow its search for prior versions to the values the upload carries. Empty when none is declared, which is the unrestricted search. Unlike `partition_by` and `sorted_by` this is NOT fixed at creation — it changes only which files a mutation opens, never how rows are written — so read it here rather than assuming a declaration took effect. |
**last_sync** | **str** | | [optional]
**layout** | [**TableLayout**](TableLayout.md) | The table's storage layout: `analytical`, or `point_lookup`, whose small data pages make fetching its rows by id cheap. Fixed at creation. |
**partition_by** | [**List[TablePartitionKey]**](TablePartitionKey.md) | The table's partition keys, in the order they were declared when the table was created. Empty when the table is not partitioned. A table's storage layout is fixed when the table is created and cannot be changed afterwards, so this is how to confirm a table really was created with the layout that was asked for. The field is always present: an empty array means \"no partitioning declared\", which is not the same as a response that omits the field entirely. Reported for tables in a Hotdata instant database, which are the only ones whose layout is declared here. A table discovered from an external connection always reports an empty array — its layout belongs to the upstream system, so an empty array there means \"not known from here\", not \"confirmed unpartitioned\". |
**var_schema** | **str** | |
**sorted_by** | [**List[TableSortKey]**](TableSortKey.md) | The table's sort keys, in the order they were declared when the table was created. Empty when no sort order was declared. Always present, and limited to tables in a Hotdata instant database, for the same reasons as `partition_by`. |
Expand Down
13 changes: 13 additions & 0 deletions docs/TableLayout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# TableLayout

Storage layout of a table.

## Enum

* `ANALYTICAL` (value: `'analytical'`)

* `POINT_LOOKUP` (value: `'point_lookup'`)

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)


2 changes: 2 additions & 0 deletions hotdata/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@
"SavedQueryVersionInfo",
"SubmitJobResponse",
"TableInfo",
"TableLayout",
"TablePartitionKey",
"TableProfileResponse",
"TableSortKey",
Expand Down Expand Up @@ -290,6 +291,7 @@
from hotdata.models.saved_query_version_info import SavedQueryVersionInfo as SavedQueryVersionInfo
from hotdata.models.submit_job_response import SubmitJobResponse as SubmitJobResponse
from hotdata.models.table_info import TableInfo as TableInfo
from hotdata.models.table_layout import TableLayout as TableLayout
from hotdata.models.table_partition_key import TablePartitionKey as TablePartitionKey
from hotdata.models.table_profile_response import TableProfileResponse as TableProfileResponse
from hotdata.models.table_sort_key import TableSortKey as TableSortKey
Expand Down
1 change: 1 addition & 0 deletions hotdata/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
from hotdata.models.saved_query_version_info import SavedQueryVersionInfo
from hotdata.models.submit_job_response import SubmitJobResponse
from hotdata.models.table_info import TableInfo
from hotdata.models.table_layout import TableLayout
from hotdata.models.table_partition_key import TablePartitionKey
from hotdata.models.table_profile_response import TableProfileResponse
from hotdata.models.table_sort_key import TableSortKey
Expand Down
5 changes: 4 additions & 1 deletion hotdata/models/add_managed_table_decl.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

from pydantic import BaseModel, ConfigDict, Field, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from hotdata.models.table_layout import TableLayout
from hotdata.models.table_partition_key import TablePartitionKey
from hotdata.models.table_sort_key import TableSortKey
from typing import Optional, Set
Expand All @@ -31,10 +32,11 @@ class AddManagedTableDecl(BaseModel):
""" # noqa: E501
constant_per_key: Optional[List[StrictStr]] = Field(default=None, description="Columns whose value is determined by this table's `key`: for every uploaded row, every stored row sharing its key holds the same value of these columns. Declaring this lets a keyed mutation (`delete`, `update`, `upsert`) restrict its search for prior versions to the values the upload carries, which prunes far harder than the key alone when the key's own file statistics are weak. Omit (the default) for the unrestricted search. **Correctness-affecting, not a hint.** If the assertion is false, a mutation supersedes one version of a key and appends beside another, silently duplicating it. Declare it only where the invariant is established.")
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.")
layout: Optional[TableLayout] = Field(default=None, description="Storage layout of the table: `analytical` (the default), or `point_lookup`, which writes small data pages so the table's rows can be fetched by id cheaply, which is what a vector index's answers do; analytical scans of it read more pages. Declared when the table is created and fixed thereafter.")
name: StrictStr
partition_by: Optional[List[TablePartitionKey]] = Field(default=None, description="Partition keys for this table, applied in order. Omit for no partitioning. Declared when the table is created and fixed thereafter.")
sorted_by: Optional[List[TableSortKey]] = Field(default=None, description="Sort keys for this table, applied in order. Omit for no sort order. Declared when the table is created and fixed thereafter. A table with a sort order cannot be indexed: creating any index on it is refused, so leave this empty on a table you plan to search.")
__properties: ClassVar[List[str]] = ["constant_per_key", "key", "name", "partition_by", "sorted_by"]
__properties: ClassVar[List[str]] = ["constant_per_key", "key", "layout", "name", "partition_by", "sorted_by"]

model_config = ConfigDict(
populate_by_name=True,
Expand Down Expand Up @@ -107,6 +109,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
_obj = cls.model_validate({
"constant_per_key": obj.get("constant_per_key"),
"key": obj.get("key"),
"layout": obj.get("layout"),
"name": obj.get("name"),
"partition_by": [TablePartitionKey.from_dict(_item) for _item in obj["partition_by"]] if obj.get("partition_by") is not None else None,
"sorted_by": [TableSortKey.from_dict(_item) for _item in obj["sorted_by"]] if obj.get("sorted_by") is not None else None
Expand Down
5 changes: 4 additions & 1 deletion hotdata/models/add_managed_table_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

from pydantic import BaseModel, ConfigDict, Field, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from hotdata.models.table_layout import TableLayout
from hotdata.models.table_partition_key import TablePartitionKey
from hotdata.models.table_sort_key import TableSortKey
from typing import Optional, Set
Expand All @@ -31,10 +32,11 @@ class AddManagedTableRequest(BaseModel):
""" # noqa: E501
constant_per_key: Optional[List[StrictStr]] = Field(default=None, description="Columns whose value is determined by this table's `key`: for every uploaded row, every stored row sharing its key holds the same value of these columns. Declaring this lets a keyed mutation (`delete`, `update`, `upsert`) restrict its search for prior versions to the values the upload carries, which prunes far harder than the key alone when the key's own file statistics are weak. Omit (the default) for the unrestricted search. **Correctness-affecting, not a hint.** If the assertion is false, a mutation supersedes one version of a key and appends beside another, silently duplicating it. Declare it only where the invariant is established.")
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.")
layout: Optional[TableLayout] = Field(default=None, description="Storage layout of the table: `analytical` (the default), or `point_lookup`, which writes small data pages so the table's rows can be fetched by id cheaply, which is what a vector index's answers do; analytical scans of it read more pages. Declared when the table is created and fixed thereafter.")
name: StrictStr
partition_by: Optional[List[TablePartitionKey]] = Field(default=None, description="Partition keys for this table, applied in order. Omit for no partitioning. Declared when the table is created and fixed thereafter.")
sorted_by: Optional[List[TableSortKey]] = Field(default=None, description="Sort keys for this table, applied in order. Omit for no sort order. Declared when the table is created and fixed thereafter. A table with a sort order cannot be indexed: creating any index on it is refused, so leave this empty on a table you plan to search.")
__properties: ClassVar[List[str]] = ["constant_per_key", "key", "name", "partition_by", "sorted_by"]
__properties: ClassVar[List[str]] = ["constant_per_key", "key", "layout", "name", "partition_by", "sorted_by"]

model_config = ConfigDict(
populate_by_name=True,
Expand Down Expand Up @@ -107,6 +109,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
_obj = cls.model_validate({
"constant_per_key": obj.get("constant_per_key"),
"key": obj.get("key"),
"layout": obj.get("layout"),
"name": obj.get("name"),
"partition_by": [TablePartitionKey.from_dict(_item) for _item in obj["partition_by"]] if obj.get("partition_by") is not None else None,
"sorted_by": [TableSortKey.from_dict(_item) for _item in obj["sorted_by"]] if obj.get("sorted_by") is not None else None
Expand Down
Loading
Loading