我目前正在与Slick一起迈出第一步。我对codegen特别感兴趣。为了开始,我安装了Typesafe Activator(activator-dist-1.3.7),启动了Activator ui,从模板“使用Slicks默认代码生成器”(slick-codegen-example)创建了一个新项目并启动它。
这很顺利,确实生成了源代码。打开Build.scala我注意到引用的版本非常过时(例如,使用2013年的Scala 2.10.3)。所以我检查了哪些是当前版本并替换了
scalaVersion := "2.10.3",
libraryDependencies ++= List(
"com.typesafe.slick" %% "slick" % "2.1.0",
"com.typesafe.slick" %% "slick-codegen" % "2.1.0-RC3",
"org.slf4j" % "slf4j-nop" % "1.6.4",
"com.h2database" % "h2" % "1.3.170"
),
使用在Build.scala中
scalaVersion := "2.11.7",
libraryDependencies ++= List(
"com.typesafe.slick" %% "slick" % "3.1.1",
"com.typesafe.slick" %% "slick-codegen" % "3.1.1",
"org.slf4j" % "slf4j-nop" % "1.7.13",
"com.h2database" % "h2" % "1.4.190"
),
然后我还更新了包名称(Alex:感谢您的提示!)以进行此构建。我还在create table sql代码中添加了“if now exists”,因为由于某些未知原因,db抱怨表已经存在。
因此最终创建了Tables.scala :)但是,使用示例查询运行Example.scala不会输出任何内容。经过一些研究,我明白这是因为Slick 3现在异步工作。在其他一些示例中,如果已经看到db.run被包装在Await.result中。所以我尝试了这个,这导致编译错误:
value groupBy is not a member of (String, String)
出了什么问题?我该如何解决?查询代码现在看起来像这样:
val q = Companies.join(Computers).on(_.id === _.manufacturerId).map {
case (co,cp) => (co.name, cp.name) }
Await.result(db.run(q.result), Duration.Inf).foreach { result =>
println(result.groupBy{ case (co,cp) => co }
.mapValues(_.map{ case (co,cp) => cp })
.mkString("\n")
)
}
答案 0 :(得分:0)
光滑3.0的包结构是changed。您需要使用import org.apache.hadoop.mapreduce.lib.input.{FileSplit, TextInputFormat}
import org.apache.spark.rdd.{NewHadoopRDD}
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.hadoop.io.LongWritable
import org.apache.hadoop.io.Text
val sc = new SparkContext(new SparkConf().setMaster("local"))
val fc = classOf[TextInputFormat]
val kc = classOf[LongWritable]
val vc = classOf[Text]
val path :String = "file:///home/user/test"
val text = sc.newAPIHadoopFile(path, fc ,kc, vc, sc.hadoopConfiguration)
val linesWithFileNames = text.asInstanceOf[NewHadoopRDD[LongWritable, Text]]
.mapPartitionsWithInputSplit((inputSplit, iterator) => {
val file = inputSplit.asInstanceOf[FileSplit]
iterator.map(tup => (file.getPath, tup._2))
}
)
linesWithFileNames.foreach(println)
代替slick.codegen.SourceCodeGenerator
答案 1 :(得分:0)
得到了这个运行:)除了更改版本号(见上文),我不得不:
重写Example.scala:
object Example extends App {
// connection info for a pre-populated throw-away, in-memory db for this demo, which is freshly initialized on every run
val url = "jdbc:h2:mem:test;INIT=runscript from 'src/main/sql/create.sql'"
val db = Database.forURL(url, driver = "org.h2.Driver")
// Using generated code. Our Build.sbt makes sure they are generated before compilation.
val query = Companies.join(Computers).on(_.id === _.manufacturerId).map{ case (co,cp) => (co.name, cp.name) }
val future = db.run(query.result)
future onSuccess {
case result => println(result.groupBy{ case (co,cp) => co }
.mapValues(_.map{ case (co,cp) => cp })
.mkString("\n")
)
}
future onFailure {
case t => println("Got an error: " + t.getMessage)
}
Thread.sleep(1000)
}