来看下官网的demo,这里没有任何问题,因为.format("jdbc")是隐式,我们无需关注driver的适用性,但是,程序后台任然会报错,当我们写明用数据库类型之后,也会出现说,无法create table as select,这个mysql是不允许的。但是,以前我们的spark项目是可以的,就因为我使用了,新版本的spark吗?
我知道csdn的活跃度很低,问了也是白问,stackoverflow上面,也没找到,这里,自己考虑下吧,做的很多事亲,发现都是没有文档、答案的,真的就是吃螃蟹呗。
首先我们可以这么尝试一下,果然报错的。
首先我们跑一下,看报错信息。
Exception in thread "main" java.sql.SQLException: No suitable driver
at java.sql.DriverManager.getDriver(DriverManager.java:315)
at org.apache.spark.sql.execution.datasources.jdbc.JDBCOptions$$anonfun$6.apply(JDBCOptions.scala:105)
at org.apache.spark.sql.execution.datasources.jdbc.JDBCOptions$$anonfun$6.apply(JDBCOptions.scala:105)
at scala.Option.getOrElse(Option.scala:121)
at org.apache.spark.sql.execution.datasources.jdbc.JDBCOptions.<init>(JDBCOptions.scala:104)
at org.apache.spark.sql.execution.datasources.jdbc.JdbcOptionsInWrite.<init>(JDBCOptions.scala:193)
at org.apache.spark.sql.execution.datasources.jdbc.JdbcOptionsInWrite.<init>(JDBCOptions.scala:197)
at org.apache.spark.sql.execution.datasources.jdbc.JdbcRelationProvider.createRelation(JdbcRelationProvider.scala:45)
at org.apache.spark.sql.execution.datasources.SaveIntoDataSourceCommand.run(SaveIntoDataSourceCommand.scala:45)
at org.apache.spark.sql.execution.command.ExecutedCommandExec.sideEffectResult$lzycompute(commands.scala:70)
at org.apache.spark.sql.execution.command.ExecutedCommandExec.sideEffectResult(commands.scala:68)
at org.apache.spark.sql.execution.command.ExecutedCommandExec.doExecute(commands.scala:86)
at org.apache.spark.sql.execution.SparkPlan$$anonfun$execute$1.apply(SparkPlan.scala:131)
at org.apache.spark.sql.execution.SparkPlan$$anonfun$execute$1.apply(SparkPlan.scala:127)
at org.apache.spark.sql.execution.SparkPlan$$anonfun$executeQuery$1.apply(SparkPlan.scala:155)
at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:151)
at org.apache.spark.sql.execution.SparkPlan.executeQuery(SparkPlan.scala:152)
at org.apache.spark.sql.execution.SparkPlan.execute(SparkPlan.scala:127)
at org.apache.spark.sql.execution.QueryExecution.toRdd$lzycompute(QueryExecution.scala:80)
at org.apache.spark.sql.execution.QueryExecution.toRdd(QueryExecution.scala:80)
at org.apache.spark.sql.DataFrameWriter$$anonfun$runCommand$1.apply(DataFrameWriter.scala:668)
at org.apache.spark.sql.DataFrameWriter$$anonfun$runCommand$1.apply(DataFrameWriter.scala:668)
at org.apache.spark.sql.execution.SQLExecution$$anonfun$withNewExecutionId$1.apply(SQLExecution.scala:78)
at org.apache.spark.sql.execution.SQLExecution$.withSQLConfPropagated(SQLExecution.scala:125)
所以,官网因为版本的关系,不一定对了。这个很正常,例如我们玩lol,官方的技能介绍、技能伤害都不更新了,也是没有办法,毕竟用人家的东西嘛。
好的,就不要硬刚了,我们换。
.format("com.mysql.jdbc.Driver")
新的问题来了,注意,写mysql的mode,有两种,一种是overwrite,另一种是append。
他底层的源码,我们可能稍后要去读一下,但是报错信息可以看到。是在create table as select
Exception in thread "main" java.lang.RuntimeException: com.mysql.jdbc.Driver does not allow create table as select.
at scala.sys.package$.error(package.scala:27)
at org.apache.spark.sql.execution.datasources.DataSource.planForWriting(DataSource.scala:526)
at org.apache.spark.sql.DataFrameWriter.saveToV1Source(DataFrameWriter.scala:281)
at org.apache.spark.sql.DataFrameWriter.save(DataFrameWriter.scala:270)
这个问题,大家看到了吧,严格按照官网都不行,是不是。
我查了一下,我用的spark版本是2.4.0,非常的新。。。官网的文档时2.2.3,我们要找下最新文档了。
查了一下2.4.4最最新的也是这样的,没办法,我们要不看下源码吧,看他怎么实现的。
关于源码部分,我要看一下,才能来给出解决方案,先找到他具体是不是这么写的。
我们现在解决思路如下:
1.能否解决mysql的create table as select 这个,但是恐怕不太可行
2.看下spark源码,能否找到别的方式,但是恐怕也不太可行,因为写入模式只有两个,overwrite、append
3.找到一个更好的写入方式,我已经有初步的思路,就是遍历循环,创立连接,insert语句硬刚,但是这样效率不仅仅低,而且,是不是傻傻的?
4.找到bug原因提交给spark团队,让他们帮我改,,,这个我觉得最靠谱