>我最近开始发现Databricks,并面临需要删除增量表的某一列的情况。当我使用PostgreSQL时,它就像
ALTER TABLE main.metrics_table
DROP COLUMN metric_1;
我正在浏览有关 DELETE 的数据砖文档,但它只涵盖 DELETE the rows that match a predicate
.
我还找到了有关 DROP 数据库、DROP 函数和 DROP 表的文档,但绝对没有关于如何从增量表中删除列的文档。我在这里错过了什么?是否有从增量表中删除列的标准方法?
Databricks 表上没有删除列选项:https://docs.databricks.com/spark/latest/spark-sql/language-manual/alter-table-or-view.html#delta-schema-constructs
请记住,与关系数据库不同,存储中有物理镶木地板文件,您的"表"只是已应用于它们的架构。
在关系世界中,您可以更新表元数据以轻松删除列,在大数据世界中,您必须重写基础文件。
从技术上讲,镶木地板可以处理架构演变(请参阅镶木地板格式的架构演变)。但是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
选项,以便它使用数据帧包含的新架构重新创建物理文件。
步骤分解:
- 读取数据框中的表。
- 将不需要的列放在最终表内
- 删除已从中读取数据的实际表。 现在,将
- 列删除为相同的表名后,将新创建的数据框保存。
- 但请确保在将数据帧另存为表时使用两个选项。(.mode("overwrite").option("overwriteSchema", "true") )
上述步骤将帮助您重新创建删除额外列的同一表。希望它能帮助面临类似问题的人。
Databricks 运行时 10.2+ 支持删除列(如果启用列映射模式)
ALTER TABLE <table_name> SET TBLPROPERTIES (
'delta.minReaderVersion' = '2',
'delta.minWriterVersion' = '5',
'delta.columnMapping.mode' = 'name'
)
然后滴剂会起作用——
ALTER TABLE table_name DROP COLUMN col_name
ALTER TABLE table_name DROP COLUMNS (col_name_1, col_name_2, ...)
如果表不是太大,则可以覆盖没有列的表。
df = spark.read.table('table')
df = df.drop('col')
df.write.format('delta')
.option("overwriteSchema", "true")
.mode('overwrite')
.saveAsTable('table')
从 Delta Lake 1.2 开始,您可以删除列,请参阅最新的 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|
+--------+
仅当您在创建表后添加了列时,它才有效。
如果是这样,并且您可以恢复更改表后插入的数据,则可以考虑使用表历史记录将表还原到以前的版本。
跟
DESCRIBE HISTORY <TABLE_NAME>
您可以检查表的所有可用版本(操作"添加列"将创建一个新的表版本)。
之后,使用RESTORE
可以将表转换为任何可用状态。
RESTORE <TALBE_NAME> VERSION AS OF <VERSION_NUMBER>
在这里,您可以获得有关时间旅行的更多信息