【问题标题】:ClassCastException in Spark Read Teradata and Write ParquetSpark 中的 ClassCastException 读取 Teradata 和写入 Parquet
【发布时间】:2021-07-16 04:57:00
【问题描述】:

我正在运行一个 Spark 作业,它使用来自 Teradata DBMS 的 SQL 查询读取 DataFrame。

当作业将文件作为拼花在 S3 上写入时,作为

partition_keys = ["Cat$col1", "Cat$col2"]
df.write.mode("overwrite").partitionBy(partition_keys)

以下java.lang.ClassCastException 异常被抛出:

File "/lib/python3.7/site-packages/pyspark/python/lib/pyspark.zip/pyspark/sql/readwriter.py", line 1249, in parquet
  File "/lib/python3.7/site-packages/pyspark/python/lib/py4j-0.10.9-src.zip/py4j/java_gateway.py", line 1305, in __call__
  File "/lib/python3.7/site-packages/pyspark/python/lib/pyspark.zip/pyspark/sql/utils.py", line 111, in deco
  File "/lib/python3.7/site-packages/pyspark/python/lib/py4j-0.10.9-src.zip/py4j/protocol.py", line 328, in get_return_value
py4j.protocol.Py4JJavaError: An error occurred while calling o58.parquet.
: java.lang.ClassCastException: class java.util.ArrayList cannot be cast to class java.lang.String (java.util.ArrayList and java.lang.String are in module java.base of loader 'bootstrap')

DataFrame 的架构是:

StructType(List(StructField(Cat$col1,IntegerType,true),StructField(Cat$col2,StringType,true),StructField(Cat$col3,DateType,true),StructField(Cat$col4,DecimalType(13,2),true),StructField(Cat$col5,IntegerType,true),StructField(Cat$col6,IntegerType,true),StructField(Cat$col7,StringType,true),StructField(Cat$col8,StringType,true),StructField(Cat$col9,StringType,true),StructField(Cat$col10,StringType,true)))
root
 |-- Cat$col1: integer (nullable = true)
 |-- Cat$col2: string (nullable = true)
 |-- Cat$col3: date (nullable = true)
 |-- Cat$col4: decimal(13,2) (nullable = true)
 |-- Cat$col5: integer (nullable = true)
 |-- Cat$col6: integer (nullable = true)
 |-- Cat$col7: string (nullable = true)
 |-- Cat$col8: string (nullable = true)
 |-- Cat$col9: string (nullable = true)
 |-- Cat$col10: string (nullable = true)

注意:架构未明确指定,因为 Spark 在尝试强加架构时会引发另一个异常,并建议在读取数据时不要指定架构。

目前尚不清楚在 Spark DataFrame 中创建 ArrayList 的位置和原因,现在无法将其转换为 String。

【问题讨论】:

  • 在尝试写入 parquet 之前,对数据帧调用的 printSchema() 的输出是什么?
  • @David 更新了问题并包含了架构。
  • 您可以尝试使用 dataframe .limit() 函数来识别导致序列化失败的第一个违规记录吗?另外,您可以尝试删除列以识别违规列吗?
  • 请添加原始 Teradata 架构
  • @shay__ 完成。请检查

标签: java apache-spark pyspark schema classcastexception


【解决方案1】:

问题在于partition_keys 之前缺少* 以解压缩列表。问题解决如下:

partition_keys = ["Cat$col1", "Cat$col2"]
df.write.mode("overwrite").partitionBy(*partition_keys)

混淆是因为错误消息java.lang.ClassCastException: class java.util.ArrayList cannot be cast to class java.lang.String。似乎 python 列表正在被转换为 Java 中的 ArrayList,然后无法转换为 String 以用作分区名称。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-18
    • 2020-05-17
    • 2018-10-27
    • 2018-03-11
    • 2018-01-31
    • 2017-10-31
    • 2017-01-16
    • 2020-12-14
    相关资源
    最近更新 更多