Как удалить столбец из таблицы Дельтабрик Дельта?
Недавно я начал обнаруживать блоки данных и столкнулся с ситуацией, когда мне нужно отбросить определенный столбец дельта-таблицы. Когда я работал с PostgreSQL, это было так же просто, как
ALTER TABLE main.metrics_table
DROP COLUMN metric_1;
Я просматривал документацию Databricks на DELETE, но она охватывает только DELETE the rows that match a predicate
,
Я также нашел документы по базе данных DROP, функции DROP и таблице DROP, но абсолютно ничего о том, как удалить столбец из дельта-таблицы. Что мне здесь не хватает? Существует ли стандартный способ удаления столбца из дельта-таблицы?
7 ответов
В таблицах Databricks отсутствует опция удаления столбца: https://docs.databricks.com/spark/latest/spark-sql/language-manual/alter-table-or-view.html
Помните, что в отличие от реляционной базы данных в вашем хранилище есть физические файлы паркета, ваша "таблица" - это просто схема, которая была применена к ним.
В реляционном мире вы можете обновить метаданные таблицы, чтобы легко удалить столбец, а в мире больших данных вы должны переписать базовые файлы.
Технически паркет может обрабатывать эволюцию схемы (см. Эволюцию схемы в формате паркета). Но реализация Databricks Delta этого не делает. Возможно, это слишком сложно, чтобы стоить того.
Поэтому решение в этом случае состоит в том, чтобы создать новую таблицу и вставить столбцы, которые вы хотите сохранить от старой таблицы.
Используйте код ниже:
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>")
Databricks Runtime 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, ...)
Один из способов, который я придумал для выполнения этой работы, - это сначала удалить таблицу, а затем воссоздать таблицу из фрейма данных, используя для параметра overwriteSchema значение true. Вам также необходимо использовать параметр mode = overwrite, чтобы он воссоздал физические файлы с использованием новой схемы, содержащейся в фрейме данных.
Разбивка шагов:
- Прочтите таблицу в фрейме данных.
- Отбросьте столбцы, которые вам не нужны в финальной таблице
- Отбросьте фактическую таблицу, из которой вы прочитали данные.
- теперь сохраните вновь созданный фрейм данных после удаления столбцов с тем же именем таблицы.
- но убедитесь, что вы используете две опции во время сохранения фрейма данных в виде таблицы.. (.mode ("overwrite"). option ("overwriteSchema", "true"))
Вышеуказанные шаги помогут вам воссоздать ту же таблицу с удаленными лишними столбцами. Надеюсь, это поможет кому-то столкнуться с подобной проблемой.
Вы можете перезаписать таблицу без столбца, если таблица не слишком велика.
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|
+--------+--------+
Вот как удалить столбец:
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>
Здесь вы найдете больше информации о ПУТЕШЕСТВИИ ВО ВРЕМЕНИ