Перезаписать только некоторые разделы в разделенном искровом наборе данных

Как мы можем перезаписать секционированный набор данных, но только разделы, которые мы собираемся изменить? Например, перекомпоновать ежедневную работу на прошлой неделе и только переписать на прошлой неделе данные.

По умолчанию поведение Spark заключается в том, чтобы перезаписать всю таблицу, даже если будут записаны только некоторые разделы.

Ответ 1

Начиная с Spark 2.3.0, это вариант при перезаписи таблицы. Чтобы перезаписать его, вам необходимо установить новый параметр spark.sql.sources.partitionOverwriteMode в dynamic, необходимо, чтобы набор данных был разбит на разделы и overwrite режим записи. Пример:

spark.conf.set(
  "spark.sql.sources.partitionOverwriteMode", "dynamic"
)
data.write.mode("overwrite").insertInto("partitioned_table")

Я рекомендую сделать перераспределение на основе столбца раздела перед написанием, поэтому вы не получите 400 файлов в папке.

До Spark 2.3.0 лучшим решением было бы запустить SQL-инструкции для удаления этих разделов, а затем записать их с помощью добавления режима.

Ответ 2

Просто FYI, для пользователей PySpark обязательно установите overwrite=True в insertInto иначе режим будет изменен на append

из исходного кода:

def insertInto(self, tableName, overwrite=False):
    self._jwrite.mode(
        "overwrite" if overwrite else "append"
    ).insertInto(tableName)

вот как это использовать:

spark.conf.set("spark.sql.sources.partitionOverwriteMode","DYNAMIC")
data.write.insertInto("partitioned_table", overwrite=True)

или в версии SQL работает нормально.

INSERT OVERWRITE TABLE [db_name.]table_name [PARTITION part_spec] select_statement

посмотри здесь

Ответ 4

Добавление параметра overwrite = True в оператор insertInto решает эту проблему:

df.write.mode("overwrite").insertInto("database_name.partioned_table", overwrite=True)

По умолчанию overwrite=False. Изменение его на True позволяет нам перезаписывать определенные разделы, содержащиеся в df и в partioned_table. Это помогает нам избежать перезаписи всего содержимого partioned_table с помощью df.