Skip to content

Commit af7a73c

Browse files
committed
fixup! Add support for registering views
1 parent d59b5d8 commit af7a73c

2 files changed

Lines changed: 41 additions & 9 deletions

File tree

pyiceberg/catalog/rest/__init__.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,14 +1322,16 @@ def view_exists(self, identifier: str | Identifier) -> bool:
13221322
@retry(**_RETRY_ARGS)
13231323
def register_view(self, identifier: str | Identifier, metadata_location: str) -> View:
13241324
self._check_endpoint(Capability.V1_REGISTER_VIEW)
1325-
namespace_and_view = self._split_identifier_for_path(identifier)
1326-
request = RegisterViewRequest(
1327-
name=self._identifier_to_validated_tuple(identifier)[-1],
1328-
metadata_location=metadata_location,
1329-
)
1325+
namespace_and_view = self._split_identifier_for_path(identifier, IdentifierKind.VIEW)
1326+
namespace = namespace_and_view["namespace"]
1327+
view = namespace_and_view["view"]
1328+
if self.table_exists(identifier):
1329+
raise TableAlreadyExistsError(f"Table {namespace}.{view} already exists")
1330+
1331+
request = RegisterViewRequest(name=view, metadata_location=metadata_location)
13301332
serialized_json = request.model_dump_json().encode(UTF8)
13311333
response = self._session.post(
1332-
self.url(Endpoints.register_view, namespace=namespace_and_view["namespace"]),
1334+
self.url(Endpoints.register_view, namespace=namespace),
13331335
data=serialized_json,
13341336
)
13351337
try:

tests/catalog/test_rest.py

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2124,12 +2124,18 @@ def test_table_identifier_in_commit_table_request(
21242124

21252125

21262126
def test_register_view_200(rest_mock: Mocker, example_view_metadata_rest_json: dict[str, Any]) -> None:
2127+
rest_mock.head(
2128+
f"{TEST_URI}v1/namespaces/default/tables/registered_view",
2129+
status_code=404,
2130+
request_headers=TEST_HEADERS,
2131+
)
21272132
rest_mock.post(
21282133
f"{TEST_URI}v1/namespaces/default/register-view",
21292134
json=example_view_metadata_rest_json,
21302135
status_code=200,
21312136
request_headers=TEST_HEADERS,
21322137
)
2138+
21332139
catalog = RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN)
21342140
actual = catalog.register_view(
21352141
identifier=("default", "registered_view"), metadata_location="s3://warehouse/database/view/metadata.json"
@@ -2138,11 +2144,15 @@ def test_register_view_200(rest_mock: Mocker, example_view_metadata_rest_json: d
21382144
identifier=("default", "registered_view"),
21392145
metadata=ViewMetadata(**example_view_metadata_rest_json["metadata"]),
21402146
)
2141-
assert actual.metadata.model_dump() == expected.metadata.model_dump()
2142-
assert actual.name() == expected.name()
2147+
assert actual == expected
21432148

21442149

2145-
def test_register_view_409(rest_mock: Mocker) -> None:
2150+
def test_register_view_409_view(rest_mock: Mocker) -> None:
2151+
rest_mock.head(
2152+
f"{TEST_URI}v1/namespaces/default/tables/registered_view",
2153+
status_code=404,
2154+
request_headers=TEST_HEADERS,
2155+
)
21462156
rest_mock.post(
21472157
f"{TEST_URI}v1/namespaces/default/register-view",
21482158
json={
@@ -2164,6 +2174,26 @@ def test_register_view_409(rest_mock: Mocker) -> None:
21642174
assert "View already exists" in str(e.value)
21652175

21662176

2177+
def test_register_view_409_table(rest_mock: Mocker) -> None:
2178+
rest_mock.head(
2179+
f"{TEST_URI}v1/namespaces/default/tables/registered_view",
2180+
status_code=200,
2181+
request_headers=TEST_HEADERS,
2182+
)
2183+
rest_mock.post(
2184+
f"{TEST_URI}v1/namespaces/default/views/registered_view",
2185+
status_code=204,
2186+
request_headers=TEST_HEADERS,
2187+
)
2188+
2189+
catalog = RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN)
2190+
with pytest.raises(TableAlreadyExistsError) as e:
2191+
catalog.register_view(
2192+
identifier=("default", "registered_view"), metadata_location="s3://warehouse/database/view/metadata.json"
2193+
)
2194+
assert "Table default.registered_view already exists" in str(e.value)
2195+
2196+
21672197
def test_drop_view_invalid_namespace(rest_mock: Mocker) -> None:
21682198
view = "view"
21692199
with pytest.raises(NoSuchIdentifierError) as e:

0 commit comments

Comments
 (0)