连接到MySql的Scala Play显示运行时错误"表'令牌'不存在"

时间:2017-11-16 17:27:37

标签: mysql scala jdbc playframework

我正在尝试使用jdbc从Play for Scala控制器读取和写入远程MySQL数据库,并且SBT在运行时显示错误:

  

"表' {dbname} .token'不存在"

尽管出现此错误,但SQL调用(选择)仍按预期完成。

我的问题是:

  1. 这是什么标记'表格,我为什么要这样做?

  2. 有没有办法可以关闭“令牌”的要求'表

  3. 我用Google搜索了这个并没有找到答案,或者确实是关于这个令牌表的任何内容。

    详情如下:

    版本:

    • scala 2.11.6
    • play 2.2.6

    application.conf中的相关配置:

    evolutionplugin=disabled
    db.default.driver=com.mysql.jdbc.Driver
    db.default.url="jdbc:mysql://152.135.194.149/mydb"
    db.default.user=someuser
    db.default.password="somepassword"
    

    控制器的相关部分:

    import play.api.db._
    import play.api.Play.current
    def test = Action {
    
      DB.withConnection { conn =>
        val stm = conn.createStatement()
        val res = stm.executeQuery("""
        SELECT  *
        FROM    sometable
        """.stripMargin)
    
        while (res.next()) {
          // this println succeeds in showing the selected data
          println(res.getString(1), res.getString(2), res.getString(3), res.getString(4))
        }
    
      }
    
      Status(200)("good enough")
    } // test
    
    来自SBT的

    完整错误消息:

    [ERROR] [11/15/2017 16:31:43.041] [play-akka.actor.default-dispatcher-3] [TaskInvocation] Table 'mydb.token' doesn't exist
    com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'mydb.token' doesn't exist
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
        at com.mysql.jdbc.Util.getInstance(Util.java:386)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1054)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4237)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4169)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2617)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2778)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2825)
        at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2156)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2459)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2376)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2360)
        at com.jolbox.bonecp.PreparedStatementHandle.executeUpdate(PreparedStatementHandle.java:205)
        at anorm.Sql$class.executeUpdate(Anorm.scala:473)
        at anorm.SqlQuery.executeUpdate(Anorm.scala:481)
        at service.PgSqlUserService$$anonfun$deleteExpiredTokens$1.apply(PgSqlUserService.scala:521)
        at service.PgSqlUserService$$anonfun$deleteExpiredTokens$1.apply(PgSqlUserService.scala:512)
        at play.api.db.DBApi$class.withConnection(DB.scala:82)
        at play.api.db.BoneCPApi.withConnection(DB.scala:276)
        at play.api.db.DB$$anonfun$withConnection$3.apply(DB.scala:162)
        at play.api.db.DB$$anonfun$withConnection$3.apply(DB.scala:162)
        at scala.Option.map(Option.scala:145)
        at play.api.db.DB$.withConnection(DB.scala:162)
        at service.PgSqlUserService.deleteExpiredTokens(PgSqlUserService.scala:512)
        at securesocial.core.UserServicePlugin$$anonfun$onStart$1.apply$mcV$sp(UserService.scala:137)
        at akka.actor.Scheduler$$anon$9.run(Scheduler.scala:80)
        at akka.actor.LightArrayRevolverScheduler$$anon$3$$anon$2.run(Scheduler.scala:241)
        at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:42)
        at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:386)
        at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
        at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
        at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
        at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
    
    [error] a.d.TaskInvocation - Table 'mydb.token' doesn't exist
    com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'mydb.token' doesn't exist
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_151]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_151]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_151]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_151]
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) ~[mysql-connector-java-5.1.27.jar:na]
        at com.mysql.jdbc.Util.getInstance(Util.java:386) ~[mysql-connector-java-5.1.27.jar:na]
    

    MySQL用户的权限:

    mysql> select Host, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv, Alter_priv, Super_priv, Create_tmp_table_priv, Create_tablespace_priv from user where Host="%" and User="someuser";
    +------+------------+-------------+-------------+-------------+-------------+-------------+-----------+------------+------------+-----------------------+------------------------+
    | Host | User       | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Alter_priv | Super_priv | Create_tmp_table_priv | Create_tablespace_priv |
    +------+------------+-------------+-------------+-------------+-------------+-------------+-----------+------------+------------+-----------------------+------------------------+
    | %    | someuser   | Y           | Y           | Y           | Y           | Y           | Y         | Y          | Y          | Y                     | Y                      |
    +------+------------+-------------+-------------+-------------+-------------+-------------+-----------+------------+------------+-----------------------+------------------------+
    1 row in set (0.00 sec)
    

    备注:

    • 我还使用了使用Postgres的Securesocial。

    • 我打算将来能够进化。

    非常感谢任何帮助。提前谢谢!

1 个答案:

答案 0 :(得分:1)

该问题与securesocial竞争db.default配置有关。

由于此项目部署在heroku上,因此db。*配置在Procfile中设置,而不是在application.conf中设置,并设置为在不同的服务器上使用postgres。

在application.conf中重新声明db.default会导致securesocial尝试查询mysql数据库,因此'表标记不存在'错误。

解决方案是提供非默认的db配置并使用:

application.conf:使用' custom' (或任何其他字符串)而不是'默认'

db.custom.driver=com.mysql.jdbc.Driver
db.custom.url="jdbc:mysql://152.135.194.149/mydb"
db.custom.user=someuser
db.custom.password="somepassword"

controller:使用上面的配置

调用withConnection()
import play.api.db._
import play.api.Play.current
def test = Action {

  // note the 'custom'
  DB.withConnection("custom") { conn =>
    val stm = conn.createStatement()
    val res = stm.executeQuery("""
    SELECT  *
    FROM    sometable
    """.stripMargin)

    while (res.next()) {
      // this println succeeds in showing the selected data
      println(res.getString(1), res.getString(2), res.getString(3), res.getString(4))
    }

  }

  Status(200)("good enough")
} // test