Различные типы данных в одном столбце в паркетном разделе - PullRequest
2 голосов
/ 03 апреля 2020

Я получаю сообщение об ошибке при чтении файла PARQUET с S3, и причина в том, что столбец "final_height" получил типы String и Double в одном разделе. Для информации в файле паркета более 20 столбцов. Я получаю следующие ошибки:

ERROR 1: Failed merging schema of file ".../part1.gz.parquet":

ERROR 2: Caused by: org.apache.spark.SparkException:
Failed to merge fields 'final_height' and 'final_height'. Failed to merge incompatible data types double and string

ERROR 3: com.databricks.sql.io.FileReadException:
Error while reading file ".../part1.gz.parquet".
Parquet column cannot be converted. Column: [final_height], Expected: StringType, Found: DOUBLE

ERROR 4: com.databricks.sql.io.FileReadException:
Error while reading file ".../part1.gz.parquet".
Parquet column cannot be converted. Column: [final_height], Expected: DoubleType, Found: BINARY

ERROR 5: org.apache.spark.sql.execution.datasources.SchemaColumnConvertNotSupportedException

Найдены некоторые решения, когда "part1.gz.parquet" содержит String данные для столбца X и "part2.gz.parquet" содержит Double данных в одном столбце. Но они не работают , когда разные типы в одном и том же столбце обнаружены в одном и том же разделе.

Попытка:

  • чтение с Параметры mergeSchema и inferSchema (получено ОШИБКА 1 и 2)
  • чтение с предопределенной ручной схемой с типом String для столбца "final_height" (получено ОШИБКА 3 & 5)
  • чтение с предопределенной ручной схемой типа Double для столбца "final_height" (получена ОШИБКА 4 и 5)

Надеемся на какое-то решение:)

Спасибо!

1 Ответ

0 голосов
/ 03 апреля 2020

Идеальным подходом было бы чтение всего фрейма данных как двоичного типа (Array [Byte]), а затем приведение соответствующих значений к их совместимым типам данных, однако Spark не позволяет читать тип двойных данных как двоичный тип данных. Поэтому не удалось продолжить этот подход.

Может быть взломано, чтобы установить для свойства Spark "spark. sql .files.ignoreCorruptFiles" значение true, а затем прочитать файлы с нужной схемой. Файлы, которые не соответствуют указанной схеме, игнорируются. Результирующий набор данных содержит только данные из тех файлов, которые соответствуют указанной схеме. Таким образом, прочитайте два кадра данных, один с типом данных String, а другой с типом данных Double, а затем приведите любой из них к одному типу данных, а затем, наконец, объедините их.

val stringSchema = StructType(StructField("final_height", StringType, false) :: Nil)
val doubleSchema = StructType(StructField("final_height", DoubleType, false) :: Nil)

spark.conf.set("spark.sql.files.ignoreCorruptFiles", "true")

val stringDF = spark.read.schema(stringSchema).parquet("path/")
val doubleDF = spark.read.schema(doubleSchema).parquet("path/")
//Cast to compatible type
val doubleToStringDF = doubleDF.select(col("final_height").cast(StringType))

val finalDF = stringDF.union(doubleToStringDF)
...