Я пытаюсь сохранить 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