更新Delta Lake表模式<一个class="headerlink" href="//www.neidfyre.com/docs/delta/#update-delta-lake-table-schema" title="">

Delta Lake允许您更新表的模式。支持以下类型的更改:

  • 添加新列(任意位置)

  • 重新排序现有列

  • 重命名现有列

您可以显式地使用DDL或隐式地使用DML进行这些更改。

重要的

当您更新增量表模式时,从该表读取的流将终止。如果您希望流继续,则必须重新启动它。

推荐的方法请参见<一个class="reference internal" href="//www.neidfyre.com/docs/structured-streaming/production.html">结构化流的生产考虑因素

显式更新模式以添加列<一个class="headerlink" href="//www.neidfyre.com/docs/delta/#explicitly-update-schema-to-add-columns" title="">

改变表格table_name添加col_namedata_type评论col_comment第一个|colA_name],…)

缺省情况下,nullability为真正的

要向嵌套字段中添加列,请使用:

改变表格table_name添加col_namenested_col_namedata_type评论col_comment第一个|colA_name],…)

例如,如果运行之前的模式改变表格盒子添加(colB.nested字符串field1)是:

-|-可乐|-colB|+-field1|+-field2

后面的模式是:

-|-可乐|-colB|+-field1|+-嵌套的|+-field2

请注意

只支持为结构添加嵌套列。不支持数组和映射。

显式更新模式以更改列注释或排序<一个class="headerlink" href="//www.neidfyre.com/docs/delta/#explicitly-update-schema-to-change-column-comment-or-ordering" title="">

改变表格table_name改变col_namecol_namedata_type评论col_comment第一个|colA_name

要更改嵌套字段中的列,请使用:

改变表格table_name改变col_namenested_col_namenested_col_namedata_type评论col_comment第一个|colA_name

例如,如果运行之前的模式改变表格盒子改变colB.field2field2字符串第一个是:

-|-可乐|-colB|+-field1|+-field2

后面的模式是:

-|-可乐|-colB|+-field2|+-field1

显式更新模式以替换列<一个class="headerlink" href="//www.neidfyre.com/docs/delta/#explicitly-update-schema-to-replace-columns" title="">

改变表格table_name取代col_name1col_type1评论col_comment1],…)

例如,当运行以下DDL时:

改变表格盒子取代colC字符串colB结构体<field2字符串嵌套的字符串field1字符串>可乐字符串

如果前面的schema是:

-|-可乐|-colB|+-field1|+-field2

后面的模式是:

-|-colC|-colB|+-field2|+-嵌套的|+-field1|-可乐

显式更新模式以重命名列<一个class="headerlink" href="//www.neidfyre.com/docs/delta/#explicitly-update-schema-to-rename-columns" title="">

预览

此功能已在<一个class="reference internal" href="//www.neidfyre.com/docs/release-notes/release-types.html">公共预览

请注意

该特性在Databricks Runtime 10.2及以上版本中可用。

要重命名列而不重写任何列的现有数据,必须为表启用列映射。看到<一个class="reference internal" href="//www.neidfyre.com/docs/delta/delta-column-mapping.html">使用Delta Lake列映射重命名和删除列

重命名一个列。

改变表格table_name重命名old_col_namenew_col_name

重命名一个嵌套字段:

改变表格table_name重命名col_nameold_nested_fieldnew_nested_field

以执行以下命令为例:

改变表格盒子重命名colBfield1field001

如果前面的schema是:

-|-可乐|-colB|+-field1|+-field2

之后的模式是:

-|-可乐|-colB|+-field001|+-field2

看到<一个class="reference internal" href="//www.neidfyre.com/docs/delta/delta-column-mapping.html">使用Delta Lake列映射重命名和删除列

显式更新模式以删除列<一个class="headerlink" href="//www.neidfyre.com/docs/delta/#explicitly-update-schema-to-drop-columns" title="">

预览

此功能已在<一个class="reference internal" href="//www.neidfyre.com/docs/release-notes/release-types.html">公共预览

请注意

此特性在Databricks Runtime 11.0及以上版本中可用。

要将列作为仅元数据操作删除而不重写任何数据文件,必须为表启用列映射。看到<一个class="reference internal" href="//www.neidfyre.com/docs/delta/delta-column-mapping.html">使用Delta Lake列映射重命名和删除列

重要的

从元数据中删除列并不会删除文件中该列的基础数据。要清除已删除的列数据,可以使用<一个class="reference internal" href="//www.neidfyre.com/docs/sql/language-manual/delta-reorg-table.html">REORG表重写文件。然后你可以使用<一个class="reference internal" href="//www.neidfyre.com/docs/sql/language-manual/delta-vacuum.html">真空以物理方式删除包含已删除列数据的文件。

删除一列:

改变表格table_name下降col_name

删除多个列:

改变表格table_name下降col_name_1col_name_2

显式更新模式以更改列类型或名称<一个class="headerlink" href="//www.neidfyre.com/docs/delta/#explicitly-update-schema-to-change-column-type-or-name" title="">

您可以通过重写表来更改列的类型或名称或删除列。要做到这一点,请使用overwriteSchema选择。

更改列类型的示例如下:

火花表格...withColumn“生日”上校“生日”“日期”))模式“覆盖”选项“overwriteSchema”“真正的”saveAsTable...

更改列名的示例如下:

火花表格...withColumnRenamed“dateOfBirth”“生日”模式“覆盖”选项“overwriteSchema”“真正的”saveAsTable...

使用自动模式更新添加列<一个class="headerlink" href="//www.neidfyre.com/docs/delta/#add-columns-with-automatic-schema-update" title="">

出现在DataFrame中但从表中缺失的列会自动添加为写事务的一部分:

  • writeStream.option(“mergeSchema”,“真正的”)

  • spark.databricks.delta.schema.autoMerge.enabled真正的

属性中的选项DataFrameWriter优先。添加的列被追加到它们所在结构的末尾。在追加新列时保留大小写。

请注意

  • mergeSchema不能与插入.write.insertInto ()

Delta Lake合并的自动模式演化<一个class="headerlink" href="//www.neidfyre.com/docs/delta/#automatic-schema-evolution-for-delta-lake-merge" title="">

默认情况下,updateAll而且insertAll为目标Delta表中的所有列分配与源数据集同名的列。源数据集中与目标表中的列不匹配的任何列都将被忽略。然而,在某些用例中,需要自动向目标Delta表添加源列。

操作期间自动更新表架构合并操作updateAll而且insertAll(至少其中一个),您可以设置Spark会话配置spark.databricks.delta.schema.autoMerge.enabled真正的在运行合并操作。

请注意

  • 模式演化仅在两者之一时发生updateAll更新)或insertAll插入)行动,或两者兼有。

  • 更新而且插入操作不能显式地引用目标表中不存在的目标列(即使存在)updateAllinsertAll作为从句之一)。请看下面的例子。

请注意

在Databricks Runtime 7.4及以下版本中,合并仅支持顶级列的模式演化,而不支持嵌套列的模式演化。

这里有几个例子说明合并有和没有模式演化的操作。

查询(Scala)

没有模式演进的行为(默认)

模式演变的行为

目标列:键,价值

源列:键,值,newValue

targetDeltaTable别名“t”合并sourceDataFrame别名“s”),"t.key = s.key"whenMatched().updateAll()whenNotMatched().insertAll()执行()

表模式保持不变;只列关键价值更新/插入。

表模式更改为(关键值,newValue)updateAll更新列价值而且newValue,insertAll插入行(关键值,newValue)

目标列:键,oldValue

源列:键,newValue

targetDeltaTable别名“t”合并sourceDataFrame别名“s”),"t.key = s.key"whenMatched().updateAll()whenNotMatched().insertAll()执行()

updateAll而且insertAll操作抛出错误,因为目标列oldValue不在源头。

表模式更改为(关键oldValue,newValue)updateAll更新列关键而且newValue离开oldValue保持不变,insertAll插入行(关键空,newValue)(即,oldValue插入为).

目标列:键,oldValue

源列:键,newValue

targetDeltaTable别名“t”合并sourceDataFrame别名“s”),"t.key = s.key"whenMatched().更新地图“newValue”->上校“s.newValue”)))whenNotMatched().insertAll()执行()

更新因为列抛出错误newValue目标表中不存在。

更新仍然抛出错误,因为列newValue目标表中不存在。

目标列:键,oldValue

源列:键,newValue

targetDeltaTable别名“t”合并sourceDataFrame别名“s”),"t.key = s.key"whenMatched().updateAll()whenNotMatched().插入地图“关键”->上校“s.key”),“newValue”->上校“s.newValue”)))执行()

插入因为列抛出错误newValue目标表中不存在。

插入仍然抛出作为列的错误newValue目标表中不存在。

结构数组的自动模式演化<一个class="headerlink" href="//www.neidfyre.com/docs/delta/#automatic-schema-evolution-for-arrays-of-structs" title="">

δ合并支持按名称解析结构字段,并为结构数组演进模式。启用模式进化后,目标表模式将为结构数组进化,这也适用于数组内的任何嵌套结构。

请注意

该特性在Databricks Runtime 9.1及以上版本中可用。对于Databricks Runtime 9.0及以下版本,隐式Spark强制转换用于结构数组,以按位置解析结构字段,并且合并操作的效果与数组中结构的模式演化不一致。

下面是几个例子,说明合并操作对结构数组的影响,包括模式演化和不包括模式演化。

源模式

目标模式

没有模式演进的行为(默认)

模式演变的行为

数组>

数组>

表模式保持不变。列将按名称解析并更新或插入。

表模式保持不变。列将按名称解析并更新或插入。

数组>

数组>

更新而且插入抛出错误是因为c而且d目标表中不存在。

表架构更改为array>。c而且d插入为用于目标表中的现有项。更新而且插入用填充源表中的条目一个铸造成字符串和b作为

数组>>

数组>>

更新而且插入抛出错误是因为d目标表中不存在。

目标表架构更改为array>>。d插入为用于目标表中的现有项。

处理NullType模式更新中的列<一个class="headerlink" href="//www.neidfyre.com/docs/delta/#dealing-with-nulltype-columns-in-schema-updates" title="">

因为Parquet不支持NullTypeNullType当写入Delta表时,列从DataFrame中删除,但仍然存储在模式中。当接收到该列的不同数据类型时,Delta Lake将模式合并为新数据类型。如果三角洲湖收到NullType对于现有列,在写入过程中保留旧模式,而删除新列。

NullType不支持In流。因为你必须在使用流时设置模式,这应该是非常罕见的。NullType也不接受复杂类型,如ArrayType而且MapType

替换表模式<一个class="headerlink" href="//www.neidfyre.com/docs/delta/#replace-table-schema" title="">

默认情况下,覆盖表中的数据不会覆盖模式。重写表时使用模式(“覆盖”)没有replaceWhere,您可能仍然希望覆盖正在写入的数据的模式。属性替换表的模式和分区overwriteSchema选项真正的

df选项“overwriteSchema”“真正的”