Skip to content

Commit 8d24582

Browse files
(IcebergIO) document writeProperties param more clearly (#39645)
* (IcebergIO) bugfix: wire writeProperties through table create request, not DataWriteBuilder * Test all dynamic write properties are propagated in managedio * Revert changes and document writeProperties * improve documentation
1 parent f0da6f3 commit 8d24582

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/IcebergIO.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,16 @@ public WriteRows withAutosharding() {
490490
return toBuilder().setAutoSharding(true).build();
491491
}
492492

493+
/**
494+
* Defines properties to be passed to the Iceberg writer itself. Note that these properties are
495+
* execution-scoped, meaning that they are applied to a preexisting table and will not mutate
496+
* any table-level properties.
497+
*
498+
* <p>To set table-level properties that will be applied to dynamically created tables, use the
499+
* managed Iceberg transform instead, setting the `table_properties` config property.
500+
*
501+
* <p>See: https://iceberg.apache.org/docs/latest/configuration/#write-properties
502+
*/
493503
public WriteRows withWriteProperties(Map<String, String> writeProperties) {
494504
return toBuilder().setWriteProperties(writeProperties).build();
495505
}

sdks/java/io/iceberg/src/test/java/org/apache/beam/sdk/io/iceberg/IcebergWriteSchemaTransformProviderTest.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import static org.apache.iceberg.util.DateTimeUtil.timestampFromMicros;
2626
import static org.hamcrest.MatcherAssert.assertThat;
2727
import static org.junit.Assert.assertEquals;
28+
import static org.junit.Assert.assertTrue;
2829
import static org.junit.Assume.assumeTrue;
2930

3031
import java.time.LocalDate;
@@ -62,6 +63,8 @@
6263
import org.apache.iceberg.CatalogUtil;
6364
import org.apache.iceberg.DistributionMode;
6465
import org.apache.iceberg.PartitionSpec;
66+
import org.apache.iceberg.SortDirection;
67+
import org.apache.iceberg.SortOrder;
6568
import org.apache.iceberg.Table;
6669
import org.apache.iceberg.catalog.TableIdentifier;
6770
import org.apache.iceberg.data.IcebergGenerics;
@@ -693,4 +696,64 @@ public void testWriteCreateTableWithTableProperties() {
693696
assertEquals("5", table.properties().get("commit.retry.num-retries"));
694697
assertEquals("134217728", table.properties().get("read.split.target-size"));
695698
}
699+
700+
@Test
701+
public void testDynamicWriteCreateTableWithTableProperties() {
702+
String identifier = "default.table_" + Long.toString(UUID.randomUUID().hashCode(), 16);
703+
Schema schema = Schema.builder().addStringField("str").addInt32Field("int").build();
704+
705+
String customDataPath = warehouse.location + "/custom_data_path";
706+
707+
Map<String, Object> config =
708+
ImmutableMap.of(
709+
"table",
710+
identifier,
711+
"catalog_properties",
712+
ImmutableMap.of("type", "hadoop", "warehouse", warehouse.location),
713+
"table_properties",
714+
ImmutableMap.of(
715+
"write.data.path",
716+
customDataPath,
717+
"write.parquet.bloom-filter-enabled.column.int",
718+
"true"),
719+
"sort_fields",
720+
Collections.singletonList("str desc"),
721+
"partition_fields",
722+
Collections.singletonList("int"));
723+
724+
List<Row> rows = new ArrayList<>();
725+
for (int i = 0; i < 10; i++) {
726+
Row row = Row.withSchema(schema).addValues("str_" + i, i).build();
727+
rows.add(row);
728+
}
729+
730+
PCollection<Row> result =
731+
testPipeline
732+
.apply("Records To Add", Create.of(rows))
733+
.setRowSchema(schema)
734+
.apply(Managed.write(Managed.ICEBERG).withConfig(config))
735+
.get(SNAPSHOTS_TAG);
736+
737+
PAssert.that(result)
738+
.satisfies(new VerifyOutputs(Collections.singletonList(identifier), "append"));
739+
testPipeline.run().waitUntilFinish();
740+
741+
Table table = warehouse.loadTable(TableIdentifier.parse(identifier));
742+
743+
PartitionSpec spec = table.spec();
744+
assertTrue(spec.isPartitioned());
745+
assertEquals(1, spec.fields().size());
746+
assertEquals("int", spec.fields().get(0).name());
747+
748+
SortOrder sortOrder = table.sortOrder();
749+
assertTrue(sortOrder.isSorted());
750+
assertEquals(1, sortOrder.fields().size());
751+
assertEquals(SortDirection.DESC, sortOrder.fields().get(0).direction());
752+
753+
assertEquals(customDataPath, table.properties().get("write.data.path"));
754+
assertEquals("true", table.properties().get("write.parquet.bloom-filter-enabled.column.int"));
755+
756+
List<Record> writtenRecords = ImmutableList.copyOf(IcebergGenerics.read(table).build());
757+
assertEquals(10, writtenRecords.size());
758+
}
696759
}

0 commit comments

Comments
 (0)