Skip to content

Commit 781096e

Browse files
authored
Add table_exists method to Catalog (#512)
* Add `table_exist` method to Catalog * `table_exist` -> `table_exists` * Add `table_exists` for RestCatalog * Add doc
1 parent 36a505f commit 781096e

File tree

5 files changed

+56
-0
lines changed

5 files changed

+56
-0
lines changed

mkdocs/docs/api.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,16 @@ static_table = StaticTable.from_metadata(
194194

195195
The static-table is considered read-only.
196196

197+
## Check if a table exists
198+
199+
To check whether the `bids` table exists:
200+
201+
```python
202+
catalog.table_exists("docs_example.bids")
203+
```
204+
205+
Returns `True` if the table already exists.
206+
197207
## Write support
198208

199209
With PyIceberg 0.6.0 write support is added through Arrow. Let's consider an Arrow Table:

pyiceberg/catalog/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,13 @@ def purge_table(self, identifier: Union[str, Identifier]) -> None:
646646
delete_files(io, prev_metadata_files, PREVIOUS_METADATA)
647647
delete_files(io, {table.metadata_location}, METADATA)
648648

649+
def table_exists(self, identifier: Union[str, Identifier]) -> bool:
650+
try:
651+
self.load_table(identifier)
652+
return True
653+
except NoSuchTableError:
654+
return False
655+
649656
@staticmethod
650657
def _write_metadata(metadata: TableMetadata, io: FileIO, metadata_path: str) -> None:
651658
ToOutputFile.table_metadata(metadata, io.new_output(metadata_path))

pyiceberg/catalog/rest.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,3 +717,11 @@ def update_namespace_properties(
717717
updated=parsed_response.updated,
718718
missing=parsed_response.missing,
719719
)
720+
721+
@retry(**_RETRY_ARGS)
722+
def table_exists(self, identifier: Union[str, Identifier]) -> bool:
723+
identifier_tuple = self.identifier_to_tuple_without_catalog(identifier)
724+
response = self._session.head(
725+
self.url(Endpoints.load_table, prefixed=True, **self._split_identifier_for_path(identifier_tuple))
726+
)
727+
return response.status_code == 200

tests/catalog/test_base.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,17 @@ def test_table_raises_error_on_table_not_found(catalog: InMemoryCatalog) -> None
413413
catalog.load_table(TEST_TABLE_IDENTIFIER)
414414

415415

416+
def test_table_exists(catalog: InMemoryCatalog) -> None:
417+
# Given
418+
given_catalog_has_a_table(catalog)
419+
# Then
420+
assert catalog.table_exists(TEST_TABLE_IDENTIFIER)
421+
422+
423+
def test_table_exists_on_table_not_found(catalog: InMemoryCatalog) -> None:
424+
assert not catalog.table_exists(TEST_TABLE_IDENTIFIER)
425+
426+
416427
def test_drop_table(catalog: InMemoryCatalog) -> None:
417428
# Given
418429
given_catalog_has_a_table(catalog)

tests/catalog/test_rest.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,26 @@ def test_load_table_404(rest_mock: Mocker) -> None:
644644
assert "Table does not exist" in str(e.value)
645645

646646

647+
def test_table_exist_200(rest_mock: Mocker) -> None:
648+
rest_mock.head(
649+
f"{TEST_URI}v1/namespaces/fokko/tables/table",
650+
status_code=200,
651+
request_headers=TEST_HEADERS,
652+
)
653+
catalog = RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN)
654+
assert catalog.table_exists(("fokko", "table"))
655+
656+
657+
def test_table_exist_500(rest_mock: Mocker) -> None:
658+
rest_mock.head(
659+
f"{TEST_URI}v1/namespaces/fokko/tables/table",
660+
status_code=500,
661+
request_headers=TEST_HEADERS,
662+
)
663+
catalog = RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN)
664+
assert not catalog.table_exists(("fokko", "table"))
665+
666+
647667
def test_drop_table_404(rest_mock: Mocker) -> None:
648668
rest_mock.delete(
649669
f"{TEST_URI}v1/namespaces/fokko/tables/does_not_exists",

0 commit comments

Comments
 (0)