Как удалить столбец из таблицы Дельтабрик Дельта?

Недавно я начал обнаруживать блоки данных и столкнулся с ситуацией, когда мне нужно отбросить определенный столбец дельта-таблицы. Когда я работал с 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, чтобы он воссоздал физические файлы с использованием новой схемы, содержащейся в фрейме данных.

Разбивка шагов:

  1. Прочтите таблицу в фрейме данных.
  2. Отбросьте столбцы, которые вам не нужны в финальной таблице
  3. Отбросьте фактическую таблицу, из которой вы прочитали данные.
  4. теперь сохраните вновь созданный фрейм данных после удаления столбцов с тем же именем таблицы.
  5. но убедитесь, что вы используете две опции во время сохранения фрейма данных в виде таблицы.. (.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>

Здесь вы найдете больше информации о ПУТЕШЕСТВИИ ВО ВРЕМЕНИ

Другие вопросы по тегам