Я пытаюсь сохранить DataFrame в HDFS в формате Паркета, используя DataFrameWriter, разделенный на три значения столбца, например:
dataFrame.write.mode(SaveMode.Overwrite).partitionBy("eventdate", "hour", "processtime").parquet(path)
Как уже упоминалось в этом вопросе, partitionBy удалит всю существующую иерархию разделов в path и заменит их на разделы в DataFrame. Поскольку новые инкрементные данные для определенного дня будут поступать периодически, я хочу заменить только те разделы в иерархии, для которых DataFrame имеет данные, а остальные остаются нетронутыми.
Для этого мне нужно сохранить каждый раздел отдельно, используя его полный путь, примерно так:
singlePartition.write.mode(SaveMode.Overwrite).parquet(path + "/eventdate=2017-01-01/hour=0/processtime=1234567890")
Однако у меня возникли проблемы с пониманием лучшего способа организации данных в однораздельный DataFrame, чтобы я мог писать их с помощью их полного пути. Одна идея была примерно такой:
dataFrame.repartition("eventdate", "hour", "processtime").foreachPartition ...
Но foreachPartition работает с Iterator[Row], который не идеален для записи в формат Паркета.
Я также рассмотрел использование select...distinct eventdate, hour, processtime для получения списка разделов, а затем фильтрацию исходного фрейма данных каждым из этих разделов и сохранение результатов до их полного секционированного пути. Но отдельный запрос плюс фильтр для каждого раздела не кажется очень эффективным, так как это будет много операций фильтрации/записи.
Я надеюсь, что существует более чистый способ сохранить существующие разделы, для которых DataFrame не имеет данных?
Спасибо за чтение.
Искра версия: 2.1