20

I have recently started discovering Databricks and faced a situation where I need to drop a certain column of a delta table. When I worked with PostgreSQL it was as easy as

ALTER TABLE main.metrics_table 
DROP COLUMN metric_1;

I was looking through Databricks documentation on DELETE but it covers only DELETE the rows that match a predicate.

I've also found docs on DROP database, DROP function and DROP table but absolutely nothing on how to delete a column from a delta table. What am I missing here? Is there a standard way to drop a column from a delta table?

zsxwing
  • 20,270
  • 4
  • 37
  • 59
samba
  • 2,821
  • 6
  • 30
  • 85

7 Answers7

17

There is no drop column option on Databricks tables: https://docs.databricks.com/spark/latest/spark-sql/language-manual/alter-table-or-view.html#delta-schema-constructs

Remember that unlike a relational database there are physical parquet files in your storage, your "table" is just a schema that has been applied to them.

In the relational world you can update the table metadata to remove a column easily, in a big data world you have to re-write the underlying files.

Technically parquet can handle schema evolution (see Schema evolution in parquet format). But the Databricks implementation of Delta does not. It probably just too complicated to be worth it.

Therefore the solution in this case is to create a new table and insert the columns you want to keep from the old table.

simon_dmorias
  • 2,343
  • 3
  • 19
  • 33
  • Yeah, it's complicated when you try to add a new column that has the same name as a deleted column. – zsxwing May 16 '19 at 01:30
  • Now, creating the new table from the old table will still leave the data in the data files, correct? – zeusalmighty Aug 04 '21 at 15:02
  • 1
    @simon_dmorias could you please update your answer to reflect that dropping a column is now supported as of Delta 2.0 release? (both Databricks and otherwise) https://docs.delta.io/latest/delta-batch.html#drop-columns – Nick Karpov Aug 31 '22 at 00:01
  • 1
    There is a DROP COLUMN option in public preview since DB 11.0 – Florent Moiny Sep 19 '22 at 09:27
13

use below code :

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>")
Ardalan Shahgholi
  • 11,967
  • 21
  • 108
  • 144
7

One way that I figured out to make that work is to first drop the table and then recreate the table from the dataframe using the overwriteSchema option to true. You also need to use the option of mode = overwrite so that it recreate the physical files using new schema that the dataframe contains.

Break down of the steps :

  1. Read the table in the dataframe.
  2. Drop the columns that you don't want in your final table
  3. Drop the actual table from which you have read the data.
  4. now save the newly created dataframe after dropping the columns as the same table name.
  5. but make sure you use two options at the time of saving the dataframe as table.. (.mode("overwrite").option("overwriteSchema", "true") )

Above steps would help you recreate the same table with the extra column/s removed. Hope it helps someone facing the similar issue.

Nikunj Kakadiya
  • 2,689
  • 2
  • 20
  • 35
6

Databricks Runtime 10.2+ supports dropping columns if you enable Column Mapping mode

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

And then drops will work --

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

Tagar
  • 13,911
  • 6
  • 95
  • 110
  • This does not work for me. When setting the TBLPROPOERTIES, I get the following error message : Error in SQL statement: ParseException: no viable alternative at input 'ALTER TABLE '/my_dir/my_table''. Any idea why ? – TOMC Oct 07 '22 at 07:46
  • @TOMC use backticks for the path! – Tagar Dec 10 '22 at 00:33
3

You can overwrite the table without the column if the table isn't too large.

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

As of Delta Lake 1.2, you can drop columns, see the latest ALTER TABLE docs.

Here's a fully working example if you're interested in a snippet you can run locally:

# 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|
+--------+--------+

Here's how to drop the language column:

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

Verify that the language column isn't included in the table anymore:

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

+--------+
|speakers|
+--------+
|     1.1|
|     1.5|
|     0.6|
+--------+
Powers
  • 18,150
  • 10
  • 103
  • 108
  • This does not work for me. When setting the TBLPROPOERTIES, I get the following error message : Error in SQL statement: ParseException: no viable alternative at input 'ALTER TABLE '/my_dir/my_table''. Any idea why ? – TOMC Oct 07 '22 at 07:46
0

It works only if you added your column after creating the table.

If it is so, and if it is possible for you to recover the data inserted after altering your table, you may consider using the table history to restore the table to a previous version.

With

DESCRIBE HISTORY <TABLE_NAME> 

you can check all the available versions of your table (operation 'ADD COLUMN' will create a new table version).

Afterwards, with RESTORE it is possible to transform the table to any available state.

RESTORE <TALBE_NAME> VERSION AS OF <VERSION_NUMBER>

Here you have more information about TIME TRAVEL

Cristian Ispan
  • 571
  • 2
  • 5
  • 23