SparkDF存储目标表修改字段类型解决过程

原始问题,指定前三个字段类型后,SparkDF存储数据后出现,更改字段类型
添加插入配置进行测试

rowResult1.write
.mode(SaveMode.Overwrite)
.option("createTableColumnTypes", "check_health_id varchar(200), column_name varchar(200), row_res varchar(1000), complete int, effective int, standard int, agreement int")
.jdbc(url, "health_archives_update", prop)

测试Append插入是否会发生改变
在这里插入图片描述
在这里插入图片描述
再次使用Append模式再次插入后
在这里插入图片描述
字段类型没有发生改变
在这里插入图片描述
更换代码为overwrite模式测试
在这里插入图片描述

表字段没有发生改变。
在这里插入图片描述

再次执行任务查看
在这里插入图片描述
在这里插入图片描述

字段类型没有发生改变
测试表是否区分大小写
在这里插入图片描述

更换为小写U,测试没有影响
在这里插入图片描述
类型没有发生改变
在这里插入图片描述

PS: 此次出现的问题为SparkDF字段类型为以下所示

root 
|-- check_health_id: string (nullable = true) 
|-- column_name: string (nullable = true) 
|-- row_res: string (nullable = true) 
|-- complete: integer (nullable = true) 
|-- effective: integer (nullable = true) 
|-- standard: integer (nullable = true) 
|-- agreement: integer (nullable = true)

Mysql存储格式为

CREATE TABLE health_archives_Update ( check_health_id varchar(200) NOT NULL, column_name varchar(200), row_res varchar(1000), complete int(11) NOT NULL, effective int(11) NOT NULL, standard int(11) NOT NULL, agreement int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
当在使用rowResult1.write.mode(SaveMode.Overwrite).jdbc(url, “health_archives_update”, prop)存储时出现check_health_id、column_name、row_res统一更改字段类型为text

原因在于:

因为SparkDF中的check_health_id、column_name、row_res字段被推断为字符串类型string,而MySQL表中的该字段定义为varchar类型,所以在写入数据时Spark会尝试将string类型转换为MySQL中的varchar类型。由于varchar类型是可变长度的字符类型,因此MySQL JDBC驱动程序可能会将Spark中的string类型映射为MySQL中的text类型。
为了解决这个问题,尝试更换.option(“createTableColumnTypes”, “check_health_id varchar(200), column_name varchar(200), row_res varchar(1000), complete int, effective int, standard int, agreement int”)来指定创建表时的列类型,这样Spark就会将check_health_id、column_name、row_res字段定义为varchar(指定的数据长度)类型。

注意:

Option指定的数据类型必须要与SparkDF的列名、数据类型匹配,否则会导致写入过程发生异常(存在删除表,数据插入失败)直接跳过存储步骤结束任务
此外还必须要与Mysql表的列名和数据类型匹配,否则也会出现导入失败或发生数据转换错误。
另外,在覆盖已存在的表时,目标表的结构将不会更改,因此在这种情况下,option参数的设置可能会被忽略。