3

如何为未分区的现有 Iceberg 表添加分区?表已经加载了数据。

表已创建:

import org.apache.iceberg.hive.HiveCatalog
import org.apache.iceberg.catalog._
import org.apache.iceberg.spark.SparkSchemaUtil
import org.apache.iceberg.PartitionSpec
import org.apache.spark.sql.SaveMode._

val df1 = spark
  .range(1000)
  .toDF
  .withColumn("level",lit("something"))

val catalog = new HiveCatalog(spark.sessionState.newHadoopConf())

val icebergSchema = SparkSchemaUtil.convert(df1.schema)

val icebergTableName = TableIdentifier.of("default", "icebergTab")

val icebergTable = catalog
  .createTable(icebergTableName, icebergSchema, PartitionSpec.unpartitioned)

有什么建议么?

4

2 回答 2

4

现在,添加分区的方法是手动更新分区规范。

val table = catalog.loadTable(tableName)
val ops = table.asInstanceOf[BaseTable].operations
val spec = PartitionSpec.builderFor(table.schema).identity("level").build

val base = ops.current
val newMeta = base.updatePartitionSpec(spec)
ops.commit(base, newMeta)

有一个拉取请求来添加操作以进行更改,例如addField("level"),但这还没有完成。我认为它将在 0.11.0 版本中。

记住:

  • 更改分区规范后,现有数据文件将在分区字段的元数据表中具有空值。这并不意味着如果数据是使用新规范写入的,那么这些值就会为空,只是元数据没有现有数据文件的值。
  • 动态分区替换在新规范中将具有不同的行为,因为分区的粒度不同。没有规范,INSERT OVERWRITE将替换整个表。使用规范,只会替换具有新行的分区。为避免这种情况,我们建议使用DataFrameWriterV2Spark 中的接口,您可以更明确地了解哪些数据值被覆盖。
于 2020-10-28T16:33:10.110 回答
0

对于 Spark 3.x,您可以使用ALTER TABLE SQL 扩展将分区字段添加到现有表中:

Iceberg 支持使用以下方式向规范添加新的分区字段ADD PARTITION FIELD

spark.sql("ALTER TABLE default.icebergTab ADD PARTITION FIELD level")

添加分区字段是元数据操作,不会更改任何现有表数据。新数据将使用新分区写入,但现有数据将保留在旧分区布局中。对于元数据表中的新分区字段,旧数据文件将具有空值。

于 2022-01-02T13:42:25.330 回答