2

I am using Slick 3.1.0 on Scala 2.11.8. This is using the slick extensions to query an Oracle database.

I wrote the following code

type MyTup = (String, String, String)
implicit val actorSystem = ActorSystem()
implicit val materializer = ActorMaterializer()
val db = Database.forConfig("oracle")
val query = sql"""select col1, col2, col3 from FOO.BAR""".as[MyTup]
val source = Source.fromPublisher[MyTup](db.stream(query))
val sink = Sink.foreach[MyTup](row => println(row))
val flow = source to sink
flow.run()
readLine()
db.close()

When I run this code, this code runs for a very long time without printing anything.... which would seem to imply that its trying to read the whole result before printing (so its not streaming).

I have done streaming on MySQL and I know that it needs special configuration to enable streaming

https://github.com/slick/slick/issues/1218

Does oracle also need some special configuration like MySql?

My build.sbt

libraryDependencies ++= Seq(
   "com.typesafe.slick" % "slick-extensions_2.11" % "3.1.0",
   "com.typesafe.slick" % "slick_2.11" % "3.1.0",
   "com.typesafe.slick" % "slick-codegen_2.11" % "3.1.0",
   "oracle" % "ojdbc7_2.11" % "7.0.0",
   "com.typesafe.slick" % "slick-hikaricp_2.11" % "3.1.0",
   "com.typesafe.akka" % "akka-stream_2.11" % "2.5.4"
)
Knows Not Much
  • 30,395
  • 60
  • 197
  • 373

1 Answers1

2

OK. I found the answer. Yes Oracle driver does support streaming and it does not need any extra configuration like the mysql one.

Here is my application.conf

oracle {
  driver = "slick.jdbc.OracleProfile$"
  dataSourceClass = "slick.jdbc.DatabaseUrlDataSource"
  properties {
    driver = "oracle.jdbc.OracleDriver"
    url = "jdbc:oracle:thin:user/password@//server:1521/serviceName"
  }
  numThreads = 10
  connectionTimeout = 10000
}

My build.sbt

"com.typesafe.slick" %% "slick" % "3.2.1",
"com.typesafe.slick" %% "slick-hikaricp" % "3.2.1",
"oracle" % "ojdbc7_2.11" % "7.0.0",
"com.typesafe.akka" %% "akka-stream" % "2.5.4"

Note that I am not using slick extensions because they are obsolete. the new Oracle driver (OracleProfile) comes inside of the slick core release itself.

Only trick here is that the entry "oracle" % "ojdbc7_2.11" % "7.0.0" is fake. because I downloaded the jar and published it like this in local sbt. (oracle doesn't provide oracle driver as sbt / maven dependency)

Now this is my code and it streams data wonderfully :)

implicit val actorSystem = ActorSystem()
implicit val actorMaterializer = ActorMaterializer()
val db = Database.forConfig("oracle")
val query = sql"select member_id from foo".as[Long]
val publisher = db.stream(query)
val source = Source.fromPublisher[Long](publisher)
val sink = Sink.foreach[Long](x => println(x))
val graph = RunnableGraph.fromGraph(GraphDSL.create(sink){implicit builder => s =>
  import GraphDSL.Implicits._
  source ~> s.in
  ClosedShape
})
val future = graph.run()
Await.result(future, Duration.Inf)
db.close()
Knows Not Much
  • 30,395
  • 60
  • 197
  • 373