这个问题发生在 Spark SQL 将数据迁移进 Hive 时会出现。
Exception in thread "main" org.apache.spark.sql.AnalysisException: Cannot write incompatible data to table '`xx`.`table_name`':
- Cannot safely cast 'input_time': string to timestamp
- Cannot safely cast 'insert_time': string to timestamp
- Cannot safely cast 'modify_time': string to timestamp;
这是因为从 Spark 3.0.0
开始,Spark SQL 增加了一个安全策略,不对非同类型的数据进行强制转换,然后就会出现这个错误。
我们在源码文件 SQLConf.scala
中发现有这样一个配置 StoreAssignmentPolicy
:
其中有三种策略:
-
ANSI 策略(),不允许 Spark 进行某些不合理的类型转换,如:
string
转换成timestamp
。 -
LEGACY 策略,允许 Spark 进行类型强制转换,只要它是有效的 Cast 操作。
-
STRICT 策略,不允许 Spark 进行任何可能有损精度的转换。
解决方法:
-
修改 Spark 版本到
3.0.0
以下。(/dog) -
修改策略为 LEGACY
指定参数:spark.sql.storeAssignmentPolicy=LEGACY
如下:
val spark: SparkSession = SparkSession.
builder()
.master("local[*]")
.appName("task2_1")
.config("spark.sql.storeAssignmentPolicy","LEGACY")
.enableHiveSupport()
.getOrCreate()