|
32 | 32 | SqlCatalogBaseTable, |
33 | 33 | ) |
34 | 34 | from pyiceberg.exceptions import ( |
| 35 | + CommitFailedException, |
35 | 36 | NoSuchPropertyException, |
36 | 37 | NoSuchTableError, |
37 | 38 | TableAlreadyExistsError, |
@@ -388,6 +389,31 @@ def test_rename_table_ignores_view_rows(warehouse: Path) -> None: |
388 | 389 | assert row[0] == "VIEW" |
389 | 390 |
|
390 | 391 |
|
| 392 | +def test_commit_table_ignores_view_rows(warehouse: Path) -> None: |
| 393 | + catalog = SqlCatalog( |
| 394 | + name="test", uri=f"sqlite:///{warehouse.as_posix()}/test_commit_view.db", warehouse=f"file://{warehouse}" |
| 395 | + ) |
| 396 | + catalog.create_namespace("ns") |
| 397 | + schema = Schema(NestedField(1, "id", StringType(), required=True)) |
| 398 | + tbl = catalog.create_table(("ns", "a_view"), schema=schema) |
| 399 | + |
| 400 | + # Tamper the table row into a VIEW (simulating external writer) |
| 401 | + with catalog.engine.connect() as conn: |
| 402 | + conn.execute(text("UPDATE iceberg_tables SET iceberg_type = 'VIEW' WHERE table_name = 'a_view'")) |
| 403 | + conn.commit() |
| 404 | + |
| 405 | + # Attempting to commit table updates must fail and not modify the VIEW row |
| 406 | + with pytest.raises(CommitFailedException): |
| 407 | + with tbl.update_schema() as update: |
| 408 | + update.add_column("new_col", StringType()) |
| 409 | + |
| 410 | + # The view row must remain untouched with iceberg_type == 'VIEW' |
| 411 | + with catalog.engine.connect() as conn: |
| 412 | + row = conn.execute(text("SELECT iceberg_type FROM iceberg_tables WHERE table_name = 'a_view'")).fetchone() |
| 413 | + assert row is not None |
| 414 | + assert row[0] == "VIEW" |
| 415 | + |
| 416 | + |
391 | 417 | def test_migration_to_v1_with_property_set(warehouse: Path) -> None: |
392 | 418 | uri = f"sqlite:///{warehouse.as_posix()}/test-v1-migrate" |
393 | 419 | engine = _create_v0_db(uri) |
|
0 commit comments