[英]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
選項,以便它使用數據幀包含的新模式重新創建物理文件。
分解步驟:
上述步驟將幫助您重新創建同一個表,並刪除額外的列。 希望它可以幫助面臨類似問題的人。
只有在創建表后添加列時它才有效。
如果是這樣,並且如果您可以恢復更改表后插入的數據,則可以考慮使用表歷史記錄將表恢復到以前的版本。
和
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.