Перезаписать только некоторые разделы в разделенном искровом наборе данных
Как мы можем перезаписать секционированный набор данных, но только разделы, которые мы собираемся изменить? Например, перекомпоновать ежедневную работу на прошлой неделе и только переписать на прошлой неделе данные.
По умолчанию поведение 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
посмотри здесь
Ответ 3
До Spark 2.3.0 для этого создана JIRA. В 2.3.0 это исправлено.
https://issues.apache.org/jira/browse/SPARK-20236
Ответ 4
Добавление параметра overwrite = True в оператор insertInto решает эту проблему:
df.write.mode("overwrite").insertInto("database_name.partioned_table", overwrite=True)
По умолчанию overwrite=False
. Изменение его на True
позволяет нам перезаписывать определенные разделы, содержащиеся в df
и в partioned_table. Это помогает нам избежать перезаписи всего содержимого partioned_table с помощью df
.