diff --git a/mkdocs/docs/cli.md b/mkdocs/docs/cli.md index 28e44955d7..984e0df43d 100644 --- a/mkdocs/docs/cli.md +++ b/mkdocs/docs/cli.md @@ -219,3 +219,19 @@ Or output in JSON for automation: } } ``` + +You can also add, update or remove properties on tables or namespaces: + +```sh +➜ pyiceberg properties set table nyc.taxis write.metadata.delete-after-commit.enabled true +Set write.metadata.delete-after-commit.enabled=true on nyc.taxis + +➜ pyiceberg properties get table nyc.taxis +write.metadata.delete-after-commit.enabled true + +➜ pyiceberg properties remove table nyc.taxis write.metadata.delete-after-commit.enabled +Property write.metadata.delete-after-commit.enabled removed from nyc.taxis + +➜ pyiceberg properties get table nyc.taxis write.metadata.delete-after-commit.enabled +Could not find property write.metadata.delete-after-commit.enabled on nyc.taxis +``` diff --git a/pyiceberg/cli/console.py b/pyiceberg/cli/console.py index 6be4df12cc..edfcfb3834 100644 --- a/pyiceberg/cli/console.py +++ b/pyiceberg/cli/console.py @@ -361,9 +361,10 @@ def table(ctx: Context, identifier: str, property_name: str, property_value: str catalog, output = _catalog_and_output(ctx) identifier_tuple = Catalog.identifier_to_tuple(identifier) - _ = catalog.load_table(identifier_tuple) - output.text(f"Setting {property_name}={property_value} on {identifier}") - raise NotImplementedError("Writing is WIP") + table = catalog.load_table(identifier_tuple) + with table.transaction() as tx: + tx.set_properties({property_name: property_value}) + output.text(f"Set {property_name}={property_value} on {identifier}") @properties.group() @@ -398,8 +399,9 @@ def table(ctx: Context, identifier: str, property_name: str) -> None: # noqa: F catalog, output = _catalog_and_output(ctx) table = catalog.load_table(identifier) if property_name in table.metadata.properties: - output.exception(NotImplementedError("Writing is WIP")) - ctx.exit(1) + with table.transaction() as tx: + tx.remove_properties(property_name) + output.text(f"Property {property_name} removed from {identifier}") else: raise NoSuchPropertyException(f"Property {property_name} does not exist on {identifier}") diff --git a/tests/cli/test_console.py b/tests/cli/test_console.py index fe375eb276..a0e9552236 100644 --- a/tests/cli/test_console.py +++ b/tests/cli/test_console.py @@ -476,8 +476,8 @@ def test_properties_set_table(catalog: InMemoryCatalog) -> None: runner = CliRunner() result = runner.invoke(run, ["properties", "set", "table", "default.my_table", "location", "s3://new_location"]) - assert result.exit_code == 1 - assert "Writing is WIP" in result.output + assert result.exit_code == 0 + assert result.output == "Set location=s3://new_location on default.my_table\n" def test_properties_set_table_does_not_exist(catalog: InMemoryCatalog) -> None: @@ -518,8 +518,8 @@ def test_properties_remove_table(catalog: InMemoryCatalog) -> None: runner = CliRunner() result = runner.invoke(run, ["properties", "remove", "table", "default.my_table", "read.split.target.size"]) - assert result.exit_code == 1 - assert "Writing is WIP" in result.output + assert result.exit_code == 0 + assert result.output == "Property read.split.target.size removed from default.my_table\n" def test_properties_remove_table_property_does_not_exists(catalog: InMemoryCatalog) -> None: @@ -894,8 +894,8 @@ def test_json_properties_set_table(catalog: InMemoryCatalog) -> None: result = runner.invoke( run, ["--output=json", "properties", "set", "table", "default.my_table", "location", "s3://new_location"] ) - assert result.exit_code == 1 - assert "Writing is WIP" in result.output + assert result.exit_code == 0 + assert result.output == """"Set location=s3://new_location on default.my_table"\n""" def test_json_properties_set_table_does_not_exist(catalog: InMemoryCatalog) -> None: @@ -938,8 +938,8 @@ def test_json_properties_remove_table(catalog: InMemoryCatalog) -> None: runner = CliRunner() result = runner.invoke(run, ["--output=json", "properties", "remove", "table", "default.my_table", "read.split.target.size"]) - assert result.exit_code == 1 - assert "Writing is WIP" in result.output + assert result.exit_code == 0 + assert result.output == """"Property read.split.target.size removed from default.my_table"\n""" def test_json_properties_remove_table_property_does_not_exists(catalog: InMemoryCatalog) -> None: