0

I am having trouble to understand how to use slick profile.

My problem:

I am trying to use Slick with Akka-stream via the Alpakka JDBC plugin. The example given online is as follows:

#Load using SlickSession.forConfig("slick-h2")
slick-h2 {
  profile = "slick.jdbc.H2Profile$"
  db {
    connectionPool = disabled
    dataSourceClass = "slick.jdbc.DriverDataSource"
    properties = {
      driver = "org.h2.Driver"
      url = "jdbc:h2:/tmp/alpakka-slick-h2-test"
    }
  }
}

import scala.concurrent.Future

import akka.Done
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer

import akka.stream.scaladsl._
import akka.stream.alpakka.slick.scaladsl._

import slick.jdbc.GetResult

object SlickSourceWithPlainSQLQueryExample extends App {
  implicit val system = ActorSystem()
  implicit val mat = ActorMaterializer()
  implicit val ec = system.dispatcher

  implicit val session = SlickSession.forConfig("slick-h2")

  // The example domain
  case class User(id: Int, name: String)

  // We need this to automatically transform result rows
  // into instances of the User class.
  // Please import slick.jdbc.GetResult
  // See also: "http://slick.lightbend.com/doc/3.2.1/sql.html#result-sets"
  implicit val getUserResult = GetResult(r => User(r.nextInt, r.nextString))

  // This import enables the use of the Slick sql"...",
  // sqlu"...", and sqlt"..." String interpolators.
  // See also: "http://slick.lightbend.com/doc/3.2.1/sql.html#string-interpolation"
  import session.profile.api._

  // Stream the results of a query
  val done: Future[Done] =
    Slick
      .source(sql"SELECT ID, NAME FROM ALPAKKA_SLICK_SCALADSL_TEST_USERS".as[User])
      .log("user")
      .runWith(Sink.ignore)

  done.onComplete {
    case _ =>
      session.close()
      system.terminate()
  }
}

The issue is that it works with

implicit val session = SlickSession.forConfig("slick-h2")

I try to use slick session as follows:

object Main extends App {

  implicit val system = ActorSystem()
  implicit val mat = ActorMaterializer()
  implicit val ec = system.dispatcher

  implicit val session = SlickSession.forConfig("pp")
}

Where my pp config is as such:

pp = {

  url                 = "jdbc:oracle:thin:@52.4.90.244:1521:pp"
  driver              = oracle.jdbc.OracleDriver
  keepAliveConnection = true
  connectionPool      = disabled


  user                = "xxxxx"
  password            = "xxxxx"

}

This code breaks at runtime.

Exception in thread "main" slick.SlickException: Configured profile oracle.jdbc.OracleDriver does not conform to requested profile slick.jdbc.JdbcProfile
    at slick.basic.DatabaseConfig$.forConfig(DatabaseConfig.scala:99)
    at akka.stream.alpakka.slick.javadsl.SlickSession$.forConfig(package.scala:47)
    at akka.stream.alpakka.slick.javadsl.SlickSession$.forConfig(package.scala:44)

However in another code, where I do not use Akka-Stream and therefore do not use slickSession as such

object Main extends App {
  val db = Database.forConfig("pp")
.....}

the code works perfectly.

I concluded that this has to do with Database.forconfig("pp") and SlickSession.forConfig("slick-h2") that require 2 different things.

There is an explanation about profile in Slick website but that is not very easy to understand and provides little instruction. It does not list the available profile and their syntax.

Hence my question is, what's the difference between the two forConfig. How the profile works, where are they needed. Why the two configuration files for the database are not dealt with the same way.

Finally and formost, what is the profile for oracle. In slick 3.2.3 Slick is now free. I could not find the profile for it as in profile = "slick.jdbc.H2Profile$"

Can someone help clarify the configuration file difference, what is expected, what the profile does, and what is the profile for Oracle ?

4

2 回答 2

1

作为@Jeffrey Chung 回答的跟进。这是解决方案。

  implicit val session = SlickSession.forConfig("pp")
  import session.profile.api._

并且配置文件应该是这样的:

pp {
  profile = "slick.jdbc.OracleProfile$"
  db {
    url                 = "..."
    driver              = oracle.jdbc.OracleDriver
    keepAliveConnection = true
    connectionPool      = disabled


    user                = "...."
    password            = "...."
  }
}
于 2018-08-26T23:38:06.780 回答
1

Slick 文档中的升级指南解释了驱动程序和配置文件之间的区别:

Slick 的driver概念已重命名为profile结束对 Slick 驱动程序与 JDBC 驱动程序的混淆......

至于AlpakkaSlickSession不接受你的配置的原因,看一下源码

object SlickSession {
  private final class SlickSessionImpl(val slick: DatabaseConfig[JdbcProfile]) extends SlickSession {
    val db: JdbcBackend#Database = slick.db
    val profile: JdbcProfile = slick.profile // <-- expects a profile
  }
  ...
}

SlickSession专门在配置中查找配置文件,这就是定义驱动程序不起作用的原因。

要为 Oracle 定义配置文件,请使用OracleProfile.

于 2018-08-24T14:41:38.383 回答