You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iceberg.apache.org by ke...@apache.org on 2024/11/14 20:08:24 UTC
(iceberg-python) branch main updated: Bug Fix: `metadata_location` to be optional in `TableResponse` (#1321)
This is an automated email from the ASF dual-hosted git repository.
kevinjqliu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-python.git
The following commit(s) were added to refs/heads/main by this push:
new 3ccdc447 Bug Fix: `metadata_location` to be optional in `TableResponse` (#1321)
3ccdc447 is described below
commit 3ccdc44735d70bd3ef6ed18b60b3eba43c4b3b44
Author: Sung Yun <10...@users.noreply.github.com>
AuthorDate: Thu Nov 14 15:08:19 2024 -0500
Bug Fix: `metadata_location` to be optional in `TableResponse` (#1321)
* make metadata_location optional
* add test for staged creation
* revert
* revert from testing
---
pyiceberg/catalog/rest.py | 3 +-
tests/catalog/test_rest.py | 75 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 76 insertions(+), 2 deletions(-)
diff --git a/pyiceberg/catalog/rest.py b/pyiceberg/catalog/rest.py
index bcfa46b7..2b48330b 100644
--- a/pyiceberg/catalog/rest.py
+++ b/pyiceberg/catalog/rest.py
@@ -156,7 +156,7 @@ _RETRY_ARGS = {
class TableResponse(IcebergBaseModel):
- metadata_location: Optional[str] = Field(alias="metadata-location")
+ metadata_location: Optional[str] = Field(alias="metadata-location", default=None)
metadata: TableMetadata
config: Properties = Field(default_factory=dict)
@@ -599,7 +599,6 @@ class RestCatalog(Catalog):
response.raise_for_status()
except HTTPError as exc:
self._handle_non_200_response(exc, {409: TableAlreadyExistsError})
-
return TableResponse(**response.json())
@retry(**_RETRY_ARGS)
diff --git a/tests/catalog/test_rest.py b/tests/catalog/test_rest.py
index 9d75154a..f8662c1b 100644
--- a/tests/catalog/test_rest.py
+++ b/tests/catalog/test_rest.py
@@ -79,6 +79,17 @@ def example_table_metadata_with_snapshot_v1_rest_json(example_table_metadata_wit
}
+@pytest.fixture
+def example_table_metadata_with_no_location(example_table_metadata_with_snapshot_v1: Dict[str, Any]) -> Dict[str, Any]:
+ return {
+ "metadata": example_table_metadata_with_snapshot_v1,
+ "config": {
+ "client.factory": "io.tabular.iceberg.catalog.TabularAwsClientFactory",
+ "region": "us-west-2",
+ },
+ }
+
+
@pytest.fixture
def example_table_metadata_no_snapshot_v1_rest_json(example_table_metadata_no_snapshot_v1: Dict[str, Any]) -> Dict[str, Any]:
return {
@@ -899,6 +910,70 @@ def test_create_table_with_given_location_removes_trailing_slash_200(
assert rest_mock.last_request.json()["location"] == location
+def test_create_staged_table_200(
+ rest_mock: Mocker,
+ table_schema_simple: Schema,
+ example_table_metadata_with_no_location: Dict[str, Any],
+ example_table_metadata_no_snapshot_v1_rest_json: Dict[str, Any],
+) -> None:
+ rest_mock.post(
+ f"{TEST_URI}v1/namespaces/fokko/tables",
+ json=example_table_metadata_with_no_location,
+ status_code=200,
+ request_headers=TEST_HEADERS,
+ )
+ rest_mock.post(
+ f"{TEST_URI}v1/namespaces/fokko/tables/fokko2",
+ json=example_table_metadata_no_snapshot_v1_rest_json,
+ status_code=200,
+ request_headers=TEST_HEADERS,
+ )
+ identifier = ("fokko", "fokko2")
+ catalog = RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN)
+ txn = catalog.create_table_transaction(
+ identifier=identifier,
+ schema=table_schema_simple,
+ location=None,
+ partition_spec=PartitionSpec(
+ PartitionField(source_id=1, field_id=1000, transform=TruncateTransform(width=3), name="id"), spec_id=1
+ ),
+ sort_order=SortOrder(SortField(source_id=2, transform=IdentityTransform())),
+ properties={"owner": "fokko"},
+ )
+ txn.commit_transaction()
+
+ actual_response = rest_mock.last_request.json()
+ expected = {
+ "identifier": {"namespace": ["fokko"], "name": "fokko2"},
+ "requirements": [{"type": "assert-create"}],
+ "updates": [
+ {"action": "assign-uuid", "uuid": "b55d9dda-6561-423a-8bfc-787980ce421f"},
+ {"action": "upgrade-format-version", "format-version": 1},
+ {
+ "action": "add-schema",
+ "schema": {
+ "type": "struct",
+ "fields": [
+ {"id": 1, "name": "id", "type": "int", "required": False},
+ {"id": 2, "name": "data", "type": "string", "required": False},
+ ],
+ "schema-id": 0,
+ "identifier-field-ids": [],
+ },
+ "last-column-id": 2,
+ },
+ {"action": "set-current-schema", "schema-id": -1},
+ {"action": "add-spec", "spec": {"spec-id": 0, "fields": []}},
+ {"action": "set-default-spec", "spec-id": -1},
+ {"action": "add-sort-order", "sort-order": {"order-id": 0, "fields": []}},
+ {"action": "set-default-sort-order", "sort-order-id": -1},
+ {"action": "set-location", "location": "s3://warehouse/database/table"},
+ {"action": "set-properties", "updates": {"owner": "bryan", "write.metadata.compression-codec": "gzip"}},
+ ],
+ }
+ assert actual_response == expected
+
+
def test_create_table_409(rest_mock: Mocker, table_schema_simple: Schema) -> None:
rest_mock.post(
f"{TEST_URI}v1/namespaces/fokko/tables",