簡體   English   中英

如何從 Databricks Delta 表中刪除列?

[英]How to drop a column from a Databricks Delta table?

我最近開始發現 Databricks 並面臨需要刪除增量表的某一列的情況。 當我使用 PostgreSQL 時,它就像

ALTER TABLE main.metrics_table 
DROP COLUMN metric_1;

我正在查看有關 DELETE 的 Databricks 文檔,但它僅涵蓋DELETE the rows that match a predicate

我還在 DROP 數據庫、DROP function 和 DROP 表上找到了文檔,但絕對沒有關於如何從增量表中刪除列的內容。 我在這里想念什么? 是否有從增量表中刪除列的標准方法?

Databricks 表上沒有刪除列選項: https ://docs.databricks.com/spark/latest/spark-sql/language-manual/alter-table-or-view.html#delta-schema-constructs

請記住,與關系數據庫不同,您的存儲中有物理 parquet 文件,您的“表”只是已應用於它們的模式。

在關系世界中,您可以更新表元數據以輕松刪除列,在大數據世界中,您必須重新編寫底層文件。

從技術上講,parquet 可以處理模式演變(請參閱parquet 格式的模式演變)。 但是 Delta 的 Databricks 實現沒有。 它可能太復雜了,不值得。

因此,這種情況下的解決方案是創建一個新表並插入要從舊表中保留的列。

使用下面的代碼:

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>")

我想出的一種方法是首先刪除表,然后使用overwriteSchema選項從數據幀重新創建表true 您還需要使用mode = overwrite選項,以便它使用數據幀包含的新模式重新創建物理文件。

分解步驟:

  1. 讀取數據框中的表格。
  2. 在最終表中刪除您不想要的列
  3. 刪除您從中讀取數據的實際表。
  4. 現在將列刪除為相同的表名后保存新創建的數據框。
  5. 但請確保在將數據幀另存為表時使用兩個選項.. ( .mode("overwrite").option("overwriteSchema", "true") )

上述步驟將幫助您重新創建同一個表,並刪除額外的列。 希望它可以幫助面臨類似問題的人。

只有在創建表后添加列時它才有效。

如果是這樣,並且如果您可以恢復更改表后插入的數據,則可以考慮使用表歷史記錄將表恢復到以前的版本。

DESCRIBE HISTORY <TABLE_NAME> 

您可以檢查表的所有可用版本(操作“添加列”將創建一個新的表版本)。

之后,使用RESTORE可以將表轉換為任何可用狀態。

RESTORE <TALBE_NAME> VERSION AS OF <VERSION_NUMBER>

在這里你有更多關於時間旅行的信息

如果表不是太大,您可以覆蓋沒有列的表。

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

如果啟用列映射模式,Databricks Runtime 10.2+ 支持刪除列

ALTER TABLE <table_name> SET TBLPROPERTIES (
  'delta.minReaderVersion' = '2',
  'delta.minWriterVersion' = '5',
  'delta.columnMapping.mode' = 'name'
)

然后drop就行了——

ALTER TABLE table_name DROP COLUMN col_name
ALTER TABLE table_name DROP COLUMNS (col_name_1, col_name_2, ...)

從 Delta Lake 2.0 開始,您可以刪除列,請參閱最新的ALTER TABLE 文檔

如果您對可以在本地運行的代碼段感興趣,這是一個完整的示例:

# create a Delta Lake
columns = ["language","speakers"]
data = [("English", "1.5"), ("Mandarin", "1.1"), ("Hindi", "0.6")]
rdd = spark.sparkContext.parallelize(data)
df = rdd.toDF(columns)

df.write.format("delta").saveAsTable("default.my_cool_table")

spark.sql("select * from `my_cool_table`").show()
+--------+--------+
|language|speakers|
+--------+--------+
|Mandarin|     1.1|
| English|     1.5|
|   Hindi|     0.6|
+--------+--------+

以下是刪除language列的方法:

spark.sql("""ALTER TABLE `my_cool_table` SET TBLPROPERTIES (
   'delta.columnMapping.mode' = 'name',
   'delta.minReaderVersion' = '2',
   'delta.minWriterVersion' = '5')""")

spark.sql("alter table `my_cool_table` drop column language")

驗證language列是否不再包含在表中:

spark.sql("select * from `my_cool_table`").show()

+--------+
|speakers|
+--------+
|     1.1|
|     1.5|
|     0.6|
+--------+

最近發布了一些修改,允許在 Databricks 中重命名 DELTA TABLES 上的列。

需要在表上設置此屬性:

ALTER TABLE <table_name> SET TBLPROPERTIES (
  'delta.minReaderVersion' = '2',
  'delta.minWriterVersion' = '5',
  'delta.columnMapping.mode' = 'name'
)

之后,您可以像往常一樣重命名該列。

ALTER TABLE <table_name> RENAME COLUMN old_col_name TO new_col_name 

檢查這個: https://docs.databricks.com/delta/delta-column-mapping.html

其他有用的鏈接:

https://docs.databricks.com/delta/delta-batch.html#rename-columns-1

https://docs.databricks.com/delta/delta-batch.html#change-column-type-or-name

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM