更新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_name.nested_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_name.nested_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_name来new_col_name
重命名一个嵌套字段:
改变表格table_name重命名列col_name.old_nested_field来new_nested_field
以执行以下命令为例:
改变表格盒子重命名列colB.field1来field001
如果前面的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_1,col_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
(插入*
)行动,或两者兼有。更新
而且插入
操作不能显式地引用目标表中不存在的目标列(即使存在)updateAll
或insertAll
作为从句之一)。请看下面的例子。
请注意
在Databricks Runtime 7.4及以下版本中,合并
仅支持顶级列的模式演化,而不支持嵌套列的模式演化。
这里有几个例子说明合并
有和没有模式演化的操作。
列 |
查询(Scala) |
没有模式演进的行为(默认) |
模式演变的行为 |
---|---|---|---|
目标列: 源列: |
targetDeltaTable.别名(“t”).合并(sourceDataFrame.别名(“s”),"t.key = s.key").whenMatched().updateAll().whenNotMatched().insertAll().执行()
|
表模式保持不变;只列 |
表模式更改为 |
目标列: 源列: |
targetDeltaTable.别名(“t”).合并(sourceDataFrame.别名(“s”),"t.key = s.key").whenMatched().updateAll().whenNotMatched().insertAll().执行()
|
|
表模式更改为 |
目标列: 源列: |
targetDeltaTable.别名(“t”).合并(sourceDataFrame.别名(“s”),"t.key = s.key").whenMatched().更新(地图(“newValue”->上校(“s.newValue”))).whenNotMatched().insertAll().执行()
|
|
|
目标列: 源列: |
targetDeltaTable.别名(“t”).合并(sourceDataFrame.别名(“s”),"t.key = s.key").whenMatched().updateAll().whenNotMatched().插入(地图(“关键”->上校(“s.key”),“newValue”->上校(“s.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强制转换用于结构数组,以按位置解析结构字段,并且合并操作的效果与数组中结构的模式演化不一致。
下面是几个例子,说明合并操作对结构数组的影响,包括模式演化和不包括模式演化。
源模式 |
目标模式 |
没有模式演进的行为(默认) |
模式演变的行为 |
---|---|---|---|
数组 |
数组 |
表模式保持不变。列将按名称解析并更新或插入。 |
表模式保持不变。列将按名称解析并更新或插入。 |
数组 |
数组 |
|
表架构更改为array |
数组 |
数组 |
|
目标表架构更改为array |
处理NullType
模式更新中的列<一个class="headerlink" href="//www.neidfyre.com/docs/delta/#dealing-with-nulltype-columns-in-schema-updates" title="">
因为Parquet不支持NullType
,NullType
当写入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”,“真正的”)