如何从 Databricks Delta table 中删除列?

How to drop a column from a Databricks Delta table?

我最近开始发现 Databricks 并遇到需要删除增量的特定列的情况 table。当我使用 PostgreSQL 时,它就像

一样简单
ALTER TABLE main.metrics_table 
DROP COLUMN metric_1;

我在 DELETE 上浏览了 Databricks documentation,但它只涵盖了 DELETE the rows that match a predicate

我还找到了有关 DROP 数据库、DROP 函数和 DROP table 的文档,但完全没有关于如何从增量 table 中删除列的文档。我在这里错过了什么?是否有标准方法从增量中删除列 table?

Databricks tables 上没有删除列选项:https://docs.databricks.com/spark/latest/spark-sql/language-manual/alter-table-or-view.html#delta-schema-constructs

请记住,与关系数据库不同的是,您的存储中存在物理镶木地板文件,您的 "table" 只是已应用于它们的模式。

在关系世界中,您可以更新 table 元数据以轻松删除列,在大数据世界中,您必须重新编写底层文件。

从技术上讲,parquet 可以处理模式演变(参见 Schema evolution in parquet format)。但是 Delta 的 Databricks 实现没有。它可能太复杂了,不值得。

因此在这种情况下的解决方案是创建一个新的 table 并插入您想要从旧的 table 中保留的列。

我想出的一种方法是先删除 table,然后使用 overwriteSchema 选项从数据框中重新创建 table true.您还需要使用 mode = overwrite 的选项,以便它使用数据框包含的新架构重新创建物理文件。

分解步骤:

  1. 读取数据框中的 table。
  2. 在最终 table
  3. 中删除不需要的列
  4. 删除您从中读取数据的实际 table。
  5. 现在在删除列后将新创建的数据框保存为相同的 table 名称。
  6. 但确保在将数据帧保存为 table 时使用两个选项。(.mode("overwrite").option("overwriteSchema", "true" ) )

以上步骤将帮助您重新创建相同的 table 并删除额外的 column/s。 希望它能帮助面临类似问题的人。

使用下面的代码:

df = spark.sql("Select * from <DB Name>.<Table Name>")

df1 = df.drop("<Column Name>")

spark.sql("DROP TABLE if exists <DB Name>.<TableName>_OLD")

spark.sql("ALTER TABLE <DB Name>.<TableName> RENAME TO <DB Name>.<Table Name>_OLD ")

df1.write.format("delta").mode("OVERWRITE").option("overwriteSchema", "true").saveAsTable("<DB Name>.<Table Name>")

仅当您在创建 table 后添加列时才有效。

如果是这样,并且您可以恢复更改 table 后插入的数据,您可以考虑使用 table 历史记录来恢复 table到以前的版本。

DESCRIBE HISTORY <TABLE_NAME> 

您可以检查 table 的所有可用版本(操作 'ADD COLUMN' 将创建一个新的 table 版本)。

之后,使用 RESTORE 可以将 table 转换为任何可用状态。

RESTORE <TALBE_NAME> VERSION AS OF <VERSION_NUMBER>

这里有更多关于TIME TRAVEL

的信息

如果 table 不是太大,您可以覆盖 table 而没有该列。

df = spark.read.table('table')
df = df.drop('col')
df.write.format('delta')\
        .option("overwriteSchema", "true")\
        .mode('overwrite')\
        .saveAsTable('table')