Каковы различия между saveAsTable и insertInto в разных SaveMode (s)?
Я пытаюсь записать DataFrame
в таблицу Hive
(на S3
) в режиме Overwrite
(необходимо для моего приложения), и мне нужно выбрать один из двух методов DataFrameWriter (Spark/Scala). Из того, что я могу прочитать в документации, df.write.saveAsTable
отличается от df.write.insertInto
в следующих отношениях:
-
saveAsTable
использует разрешение на основе имени столбца, а insertInto
использует разрешение на основе позиции - В режиме
saveAsTable
уделяет больше внимания базовой схеме существующей таблицы для принятия определенных решений.
В целом, у меня saveAsTable
впечатление, что saveAsTable
- это просто более умная версия insertInto
. В качестве альтернативы, в зависимости от insertInto
использования, можно предпочесть insertInto
Но каждый ли из этих методов сопровождается некоторыми оговорками, такими как saveAsTable
производительности в случае saveAsTable
(поскольку он содержит больше функций)? Есть ли другие различия в их поведении помимо того, что сказано (не очень ясно) в документах?
EDIT-1
Документация говорит об этом относительно insertInto
Вставляет содержимое DataFrame в указанную таблицу
и это для saveAsTable
Если таблица уже существует, поведение этой функции зависит от режима сохранения, заданного функцией mode
Теперь я могу перечислить свои сомнения
- Всегда ли
insertInto
ожидает, что таблица будет существовать? -
SaveMode
ли SaveMode
на insertInto
? - Если ответ выше, то да, тогда
- какие различия между
saveAsTable
с SaveMode.Append
и insertInto
учитывая, что таблица уже существует? -
insertInto
ли смысл insertInto
с SaveMode.Overwrite
?
Ответы
Ответ 1
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ Я уже некоторое время insertInto
и хотя я далеко не эксперт в этой области, я делюсь результатами для большего блага.
Всегда ли insertInto
ожидает, что таблица будет существовать?
Да (по названию таблицы и базе данных).
Кроме того, не все таблицы могут быть вставлены, то есть (постоянная) таблица, временное представление или временное глобальное представление хороши, но не:
-
стол с ковкой
-
таблица на основе RDD
Влияет ли SaveModes на insertInto?
(Это недавно мой вопрос тоже!)
Да, но только SaveMode.Overwrite. После того, как вы подумаете о insertInto
в другие 3 режима сохранения, не имеет особого смысла (так как он просто вставляет набор данных).
какие различия между saveAsTable с SaveMode.Append и insertInto, учитывая, что таблица уже существует?
Это очень хороший вопрос! Я бы сказал, нет, но давайте посмотрим только на один пример (надеясь, что это что-то доказывает).
scala> spark.version
res13: String = 2.4.0-SNAPSHOT
sql("create table my_table (id long)")
scala> spark.range(3).write.mode("append").saveAsTable("my_table")
org.apache.spark.sql.AnalysisException: The format of the existing table default.my_table is 'HiveFileFormat'. It doesn't match the specified format 'ParquetFileFormat'.;
at org.apache.spark.sql.execution.datasources.PreprocessTableCreation$$anonfun$apply$2.applyOrElse(rules.scala:117)
at org.apache.spark.sql.execution.datasources.PreprocessTableCreation$$anonfun$apply$2.applyOrElse(rules.scala:76)
...
scala> spark.range(3).write.insertInto("my_table")
scala> spark.table("my_table").show
+---+
| id|
+---+
| 2|
| 0|
| 1|
+---+
Имеет ли смысл вставка с SaveMode. Overwrite?
Я думаю, так как он уделяет так много внимания SaveMode.Overwrite
. Он просто воссоздает целевую таблицу.
spark.range(3).write.mode("overwrite").insertInto("my_table")
scala> spark.table("my_table").show
+---+
| id|
+---+
| 1|
| 0|
| 2|
+---+
Seq(100, 200, 300).toDF.write.mode("overwrite").insertInto("my_table")
scala> spark.table("my_table").show
+---+
| id|
+---+
|200|
|100|
|300|
+---+
Ответ 2
Еще один важный момент, который я учитываю при вставке данных в динамическую многораздельную таблицу EXISTING Hive из spark 2.xx:
df.write.mode("append").insertInto("dbName"."tableName")
Приведенная выше команда будет внутренне отображать данные в вашем "df" и добавлять только новые разделы к существующей таблице.
Надеюсь, это добавляет еще один момент в решении, когда использовать "insertInto".
Ответ 3
Недавно я начал преобразовывать свои скрипты Hive в Spark, и я все еще учусь.
Есть одно важное поведение, которое я заметил с saveAsTable и insertInto, которое не обсуждалось.
df.write.mode("overwrite"). saveAsTable ("schema.table") удаляет существующую таблицу "schema.table" и воссоздает новую таблицу на основе схемы 'df'. Схема существующей таблицы становится неактуальной и не должна совпадать с df. Меня укусило это поведение, так как моя существующая таблица была ORC, а созданная новая таблица была паркетной (Spark Default).
df.write.mode("overwrite"). insertInto ("schema.table") не удаляет существующую таблицу и ожидает, что схема существующей таблицы будет совпадать со схемой 'df'.
Я проверил время создания таблицы, используя оба параметра, и подтвердил поведение.
Исходная таблица хранится как ORC - ср. 04 сентября 21:27:33 GMT 2019
После saveAsTable (хранилище изменено на Parquet) - Ср 04 сен 21:56:23 GMT 2019 (Время создания изменено)
Исходная таблица удаленных и воссозданных (ORC) - ср. 04 сентября 21:57:38 GMT 2019
После insertInto (Still ORC) - ср. 04 сентября 21:57:38 GMT 2019 (время создания не изменено)