PySpark能否通过JDBC驱动向数据库写入字符串数组?
问题根因说明
- 第一个报错是Spark 3.1.2版本本身的限制
- Spark 3.3之前的官方JDBC数据源没有实现ArrayType到JDBC数组类型的默认转换逻辑,无论对接什么JDBC驱动,只要直接写入ArrayType类型的列,都会抛出
IllegalArgumentException: Can't get JDBC type for array<string>错误,该问题和CrateDB驱动无关。
- Spark 3.3之前的官方JDBC数据源没有实现ArrayType到JDBC数组类型的默认转换逻辑,无论对接什么JDBC驱动,只要直接写入ArrayType类型的列,都会抛出
- 第二个报错是Spark参数校验逻辑导致
createTableColumnTypes的参数会先经过Spark内置的类型校验,只有Spark本身支持的JDBC映射类型才会被放行,你传入的ARRAY不在Spark 3.1.2支持的类型列表里,校验直接失败抛出DataType array is not supported错误,该请求根本不会传递到CrateDB驱动层。
可行解决方案
- 方案1:数组转JSON字符串写入
写入前调用to_json函数将数组列转为StringType类型,写入CrateDB的STRING字段,读取时再用from_json函数转回数组即可,示例代码如下:# 写入前转换数组为JSON字符串 from pyspark.sql.functions import to_json, from_json from pyspark.sql.types import ArrayType, StringType df = df.withColumn("col1", to_json(col("col1"))) df = df.withColumn("col2", to_json(col("col2"))) # 读取时转换JSON字符串回数组 read_df = read_df.withColumn("col1", from_json(col("col1"), ArrayType(StringType()))) - 方案2:升级Spark版本实现原生数组写入
升级Spark到3.3及以上版本,该版本开始支持JDBC数组类型的原生映射,配合CrateDB JDBC驱动的数组兼容能力即可直接写入数组类型字段。
内容的提问来源于stack exchange,提问作者Cande
相关产品推荐
相关产品推荐

