重命名的列从现有数据中返回 null

问题描述 投票:0回答:1

我正在试验 Apache Iceberg,并试图了解列重命名的工作原理。在我的场景中,我正在使用存储在 AWS S3 中的现有 Parquet 文件数据湖。我的目标是使用现有文件创建 Iceberg 表,而无需移动或重写任何数据。

我能找到的有关列重命名的所有信息似乎都表明它应该可以工作。使用 Iceberg Java SDK:

icebergTable.updateSchema()
    .renameColumn("old_name", "new_name")
    .commit();

当我执行此操作并查询现有数据(其中列在 Parquet 文件中存储为“old_name”)时,我得到列“new_name”返回的所有空值。我期望原始的“old_name”值映射到“new_name”列。

这个期望有效吗?我是否遗漏了有关 Iceberg 列重命名工作原理的信息?


编辑:附加细节(对于后代 - 我不确定是否有人会对此有答案)

我进一步缩小了问题范围,它似乎仅适用于最初由 Iceberg 以外的其他东西创建的 Parquet 文件中的数据(例如,使用标准 Apache Parquet 库编写的 Parquet 文件)。可以使用 appendFile() 函数将这些文件添加到 Iceberg 表中 (

https://iceberg.apache.org/javadoc/1.6.1/org/apache/iceberg/AppendFiles.html#appendFile(org.apache.iceberg .数据文件)
)。以这种方式创建的数据,然后附加到 Iceberg 表中,似乎无法正确跟踪列重命名。 有趣的是,最初由 Iceberg 创建的 Parquet 文件也可以以相同的方式附加到另一个 Iceberg 表,并且

that

数据确实正确跟踪列重命名,即使文件被复制和/或移动从它原来的冰山位置。因此,Iceberg 创建的 Parquet 文件似乎有一些独特之处,允许他们跟踪列重命名。

parquet apache-iceberg
1个回答
0
投票
field-id

为了支持添加外部创建的 Parquet 文件,Iceberg 提供了在表本身上定义此元数据的功能。这是通过 

schema.name-mapping.default

属性完成的(此处描述:

https://iceberg.apache.org/spec/#name-mapping-serialization
)。听起来这个属性应该在任何时候非 Iceberg Parquet 文件包含在 Iceberg 表中时使用。 具体来说,在本例中,该表是使用以下代码创建的:

val nameMapping = """[ {"field-id": 1, "names": ["old_name"]} ]""" catalog.buildTable(tableId, schema) .withPartitionSpec(partitionSpec) .withProperties(mapOf(TableProperties.DEFAULT_NAME_MAPPING to nameMapping)) .create()

在表上定义这些附加信息后,原来问题中所做的列重命名现在可以工作了。

© www.soinside.com 2019 - 2024. All rights reserved.