Spark Scala读取PostgreSQL大写表名时大小写不匹配问题求助
解决Spark Scala读取PostgreSQL大写表名的大小写敏感问题
这个问题我之前对接PostgreSQL和Spark的时候也踩过坑!核心原因在于PostgreSQL对标识符(表名、列名)的大小写处理规则:
- 如果创建表时用了大写字母(比如
CREATE TABLE "TextLogs" (...)),PostgreSQL会严格保留这个大小写; - 但查询时如果不用双引号包裹表名,PostgreSQL会自动把表名转为小写去匹配,而Spark JDBC默认就是不带引号传递表名,所以才会出现找不到
textlogs表的错误。
两种可行的解决方法:
方法1:用双引号包裹表名(最直接)
修改你的dbtable参数,在表名前后加上双引号。注意在Scala字符串里要转义双引号,写法如下:
val opts = Map( "url" -> "jdbc:postgresql://localhost:5433/sparkdb", "dbtable" -> "\"TextLogs\"", // 转义双引号包裹表名 "user" -> "admin", "password" -> "mypassword" ) val df = spark.read.format("jdbc").options(opts).load()
这样Spark会把带双引号的表名原封不动传给PostgreSQL驱动,驱动发送的SQL就能正确匹配到TextLogs表了。
方法2:用子查询方式指定表名
如果需要同时做数据过滤或者复杂查询,可以把表名放在子查询里,同样用双引号包裹:
val opts = Map( "url" -> "jdbc:postgresql://localhost:5433/sparkdb", "dbtable" -> "(SELECT * FROM \"TextLogs\" WHERE id > 100) AS temp_table", "user" -> "admin", "password" -> "mypassword" ) val df = spark.read.format("jdbc").options(opts).load()
这种方式在需要自定义查询逻辑时更灵活,同时也解决了大小写匹配的问题。
额外提示:
如果你的表列名也存在大写情况,还可以在JDBC选项里加上lowerCaseSchema=false,这样Spark会保留列名的原始大小写,避免列名被自动转为小写:
val opts = Map( "url" -> "jdbc:postgresql://localhost:5433/sparkdb", "dbtable" -> "\"TextLogs\"", "user" -> "admin", "password" -> "mypassword", "lowerCaseSchema" -> "false" // 保留列名原始大小写 )
内容的提问来源于stack exchange,提问作者MrGildarts
相关产品推荐
相关产品推荐

