Skip to content

Commit a4a09ce

Browse files
feat(tables): add csv and json file format support for table loads
1 parent 4aa561d commit a4a09ce

11 files changed

Lines changed: 469 additions & 10 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Changed
1111

12+
- feat(tables): add csv and json file format support for table loads
1213
- Regenerate the client from the updated Hotdata OpenAPI spec
1314
- chore: remove datasets API and related job types
1415

docs/ConnectionsApi.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,7 @@ This endpoint does not need any parameter.
810810
811811
Load managed table from upload
812812

813-
Publish a previously-uploaded parquet file as the new contents of a managed table. The upload must reference a parquet file. Only `mode = "replace"` is supported. Concurrent loads against the same upload return 409.
813+
Publish a previously-uploaded file as the new contents of a managed table. CSV, JSON, and Parquet uploads are supported; the format is auto-detected from the upload's `Content-Type` and file contents, or set explicitly via the `format` field. Only `mode = "replace"` is supported. Concurrent loads against the same upload return 409.
814814

815815
### Example
816816

docs/DatabasesApi.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Method | HTTP request | Description
1212
[**detach_database_catalog**](DatabasesApi.md#detach_database_catalog) | **DELETE** /v1/databases/{database_id}/catalogs/{connection_id} | Detach catalog from database
1313
[**get_database**](DatabasesApi.md#get_database) | **GET** /v1/databases/{database_id} | Get database
1414
[**list_databases**](DatabasesApi.md#list_databases) | **GET** /v1/databases | List databases
15+
[**load_database_table**](DatabasesApi.md#load_database_table) | **POST** /v1/databases/{database_id}/schemas/{schema}/tables/{table}/loads | Load database table from upload
1516

1617

1718
# **add_database_schema**
@@ -706,3 +707,98 @@ This endpoint does not need any parameter.
706707

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

710+
# **load_database_table**
711+
> LoadManagedTableResponse load_database_table(database_id, var_schema, table, load_managed_table_request)
712+
713+
Load database table from upload
714+
715+
Publish a previously-uploaded file as the new contents of a table on the database's default catalog. The database-scoped equivalent of the connection-scoped managed-table load — addressed by `database_id`, so no `default_connection_id` is needed. CSV, JSON, and Parquet uploads are supported; the format is auto-detected or set via `format`. Only `mode = "replace"` is supported. Concurrent loads against the same upload return 409.
716+
717+
### Example
718+
719+
* Api Key Authentication (WorkspaceId):
720+
* Bearer Authentication (BearerAuth):
721+
722+
```python
723+
import hotdata
724+
from hotdata.models.load_managed_table_request import LoadManagedTableRequest
725+
from hotdata.models.load_managed_table_response import LoadManagedTableResponse
726+
from hotdata.rest import ApiException
727+
from pprint import pprint
728+
729+
# Defining the host is optional and defaults to https://api.hotdata.dev
730+
# See configuration.py for a list of all supported configuration parameters.
731+
configuration = hotdata.Configuration(
732+
host = "https://api.hotdata.dev"
733+
)
734+
735+
# The client must configure the authentication and authorization parameters
736+
# in accordance with the API server security policy.
737+
# Examples for each auth method are provided below, use the example that
738+
# satisfies your auth use case.
739+
740+
# Configure API key authorization: WorkspaceId
741+
configuration.api_key['WorkspaceId'] = os.environ["API_KEY"]
742+
743+
# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
744+
# configuration.api_key_prefix['WorkspaceId'] = 'Bearer'
745+
746+
# Configure Bearer authorization: BearerAuth
747+
configuration = hotdata.Configuration(
748+
access_token = os.environ["BEARER_TOKEN"]
749+
)
750+
751+
# Enter a context with an instance of the API client
752+
with hotdata.ApiClient(configuration) as api_client:
753+
# Create an instance of the API class
754+
api_instance = hotdata.DatabasesApi(api_client)
755+
database_id = 'database_id_example' # str | Database ID
756+
var_schema = 'var_schema_example' # str | Schema name
757+
table = 'table_example' # str | Table name
758+
load_managed_table_request = hotdata.LoadManagedTableRequest() # LoadManagedTableRequest |
759+
760+
try:
761+
# Load database table from upload
762+
api_response = api_instance.load_database_table(database_id, var_schema, table, load_managed_table_request)
763+
print("The response of DatabasesApi->load_database_table:\n")
764+
pprint(api_response)
765+
except Exception as e:
766+
print("Exception when calling DatabasesApi->load_database_table: %s\n" % e)
767+
```
768+
769+
770+
771+
### Parameters
772+
773+
774+
Name | Type | Description | Notes
775+
------------- | ------------- | ------------- | -------------
776+
**database_id** | **str**| Database ID |
777+
**var_schema** | **str**| Schema name |
778+
**table** | **str**| Table name |
779+
**load_managed_table_request** | [**LoadManagedTableRequest**](LoadManagedTableRequest.md)| |
780+
781+
### Return type
782+
783+
[**LoadManagedTableResponse**](LoadManagedTableResponse.md)
784+
785+
### Authorization
786+
787+
[WorkspaceId](../README.md#WorkspaceId), [BearerAuth](../README.md#BearerAuth)
788+
789+
### HTTP request headers
790+
791+
- **Content-Type**: application/json
792+
- **Accept**: application/json
793+
794+
### HTTP response details
795+
796+
| Status code | Description | Response headers |
797+
|-------------|-------------|------------------|
798+
**200** | Table loaded | - |
799+
**400** | Invalid request (bad mode, bad parquet) | - |
800+
**404** | Database, table, or upload not found | - |
801+
**409** | Upload already consumed or in flight | - |
802+
803+
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
804+

docs/JobType.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ Background job types returned by the API.
1414

1515
* `MANAGED_LOAD` (value: `'managed_load'`)
1616

17+
* `DUCKLAKE_VACUUM` (value: `'ducklake_vacuum'`)
18+
19+
* `DUCKLAKE_ORPHAN_CLEANUP` (value: `'ducklake_orphan_cleanup'`)
20+
21+
* `RESULT_DELETION` (value: `'result_deletion'`)
22+
23+
* `STALE_RESULT_CLEANUP` (value: `'stale_result_cleanup'`)
24+
25+
* `RESULT_RETENTION` (value: `'result_retention'`)
26+
1727
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
1828

1929

docs/LoadManagedTableRequest.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
# LoadManagedTableRequest
22

3-
Request body for `POST /v1/connections/{connection_id}/schemas/{schema}/tables/{table}/loads`. Publishes a previously-uploaded parquet file as the new contents of the named managed table. `mode` is fixed to `\"replace\"` today; the field is kept in the request body so future modes (e.g. append) are an additive change.
3+
Request body for `POST /v1/connections/{connection_id}/schemas/{schema}/tables/{table}/loads`. Publishes a previously-uploaded file as the new contents of the named managed table. CSV and JSON uploads are converted to columnar storage on load; Parquet uploads are published directly. `mode` is fixed to `\"replace\"` today; the field is kept in the request body so future modes (e.g. append) are an additive change.
44

55
## Properties
66

77
Name | Type | Description | Notes
88
------------ | ------------- | ------------- | -------------
9+
**format** | **str** | File format of the upload: `\"csv\"`, `\"json\"`, or `\"parquet\"`. Optional — when omitted, the format is auto-detected from the upload's `Content-Type` and, failing that, from the file contents. Provide it explicitly to override detection or when the contents are ambiguous. `\"json\"` expects newline-delimited JSON (one object per line), not a JSON array. | [optional]
910
**mode** | **str** | Load mode. Only `\"replace\"` is supported in this release. |
10-
**upload_id** | **str** | ID of a previously-staged upload (see `POST /v1/files`). The upload must reference a parquet file. The upload is claimed atomically; concurrent loads against the same `upload_id` return 409. |
11+
**upload_id** | **str** | ID of a previously-staged upload (see `POST /v1/files`). The upload is claimed atomically; concurrent loads against the same `upload_id` return 409. |
1112

1213
## Example
1314

hotdata/api/connections_api.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2603,7 +2603,7 @@ def load_managed_table(
26032603
) -> LoadManagedTableResponse:
26042604
"""Load managed table from upload
26052605
2606-
Publish a previously-uploaded parquet file as the new contents of a managed table. The upload must reference a parquet file. Only `mode = \"replace\"` is supported. Concurrent loads against the same upload return 409.
2606+
Publish a previously-uploaded file as the new contents of a managed table. CSV, JSON, and Parquet uploads are supported; the format is auto-detected from the upload's `Content-Type` and file contents, or set explicitly via the `format` field. Only `mode = \"replace\"` is supported. Concurrent loads against the same upload return 409.
26072607
26082608
:param connection_id: Connection ID (required)
26092609
:type connection_id: str
@@ -2685,7 +2685,7 @@ def load_managed_table_with_http_info(
26852685
) -> ApiResponse[LoadManagedTableResponse]:
26862686
"""Load managed table from upload
26872687
2688-
Publish a previously-uploaded parquet file as the new contents of a managed table. The upload must reference a parquet file. Only `mode = \"replace\"` is supported. Concurrent loads against the same upload return 409.
2688+
Publish a previously-uploaded file as the new contents of a managed table. CSV, JSON, and Parquet uploads are supported; the format is auto-detected from the upload's `Content-Type` and file contents, or set explicitly via the `format` field. Only `mode = \"replace\"` is supported. Concurrent loads against the same upload return 409.
26892689
26902690
:param connection_id: Connection ID (required)
26912691
:type connection_id: str
@@ -2767,7 +2767,7 @@ def load_managed_table_without_preload_content(
27672767
) -> RESTResponseType:
27682768
"""Load managed table from upload
27692769
2770-
Publish a previously-uploaded parquet file as the new contents of a managed table. The upload must reference a parquet file. Only `mode = \"replace\"` is supported. Concurrent loads against the same upload return 409.
2770+
Publish a previously-uploaded file as the new contents of a managed table. CSV, JSON, and Parquet uploads are supported; the format is auto-detected from the upload's `Content-Type` and file contents, or set explicitly via the `format` field. Only `mode = \"replace\"` is supported. Concurrent loads against the same upload return 409.
27712771
27722772
:param connection_id: Connection ID (required)
27732773
:type connection_id: str

0 commit comments

Comments
 (0)