我试图使用tminglei/slick-pg v9.0.0和光滑的3.0.0并得到一个IllegalAccessException
:
akka.actor.ActorInitializationException: exception during creation
at akka.actor.ActorInitializationException$.apply(Actor.scala:166) ~[akka-actor_2.11-2.3.11.jar:na]
...
Caused by: java.lang.RuntimeException: driverClassName specified class 'com.github.tminglei.MyPostgresDriver$' could not be loaded
at com.zaxxer.hikari.AbstractHikariConfig.setDriverClassName(AbstractHikariConfig.java:370) ~[HikariCP-java6-2.3.8.jar:na]
at slick.jdbc.HikariCPJdbcDataSource$$anonfun$forConfig$18.apply(JdbcDataSource.scala:145) ~[slick_2.11-3.0.0.jar:na]
at slick.jdbc.HikariCPJdbcDataSource$$anonfun$forConfig$18.apply(JdbcDataSource.scala:145) ~[slick_2.11-3.0.0.jar:na]
at scala.Option.map(Option.scala:146) ~[scala-library-2.11.7.jar:na]
at slick.jdbc.HikariCPJdbcDataSource$.forConfig(JdbcDataSource.scala:145) ~[slick_2.11-3.0.0.jar:na]
at slick.jdbc.HikariCPJdbcDataSource$.forConfig(JdbcDataSource.scala:135) ~[slick_2.11-3.0.0.jar:na]
at slick.jdbc.JdbcDataSource$.forConfig(JdbcDataSource.scala:35) ~[slick_2.11-3.0.0.jar:na]
at slick.jdbc.JdbcBackend$DatabaseFactoryDef$class.forConfig(JdbcBackend.scala:223) ~[slick_2.11-3.0.0.jar:na]
at slick.jdbc.JdbcBackend$$anon$3.forConfig(JdbcBackend.scala:33) ~[slick_2.11-3.0.0.jar:na]
...
Caused by: java.lang.IllegalAccessException: Class com.zaxxer.hikari.AbstractHikariConfig can not access a member of class com.github.tminglei.MyPostgresDriver$ with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:109) ~[na:1.7.0_79]
at java.lang.Class.newInstance(Class.java:373) ~[na:1.7.0_79]
at com.zaxxer.hikari.AbstractHikariConfig.setDriverClassName(AbstractHikariConfig.java:366) ~[HikariCP-java6-2.3.8.jar:na]
... 43 …
Run Code Online (Sandbox Code Playgroud) 我的play-framework项目在我的本地运行良好,但是当我尝试在heroku中部署它时,我遇到了以下错误.
2015-07-05T06:24:10.456657+00:00 app[web.1]: at com.google.inject.Guice.createInjector(Guice.java:73)
2015-07-05T06:24:10.456817+00:00 app[web.1]: at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:93)
2015-07-05T06:24:10.456702+00:00 app[web.1]: at com.google.inject.Guice.createInjector(Guice.java:62)
2015-07-05T06:24:10.456746+00:00 app[web.1]: at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:126)
2015-07-05T06:24:10.456863+00:00 app[web.1]: at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
2015-07-05T06:24:10.456909+00:00 app[web.1]: at play.core.server.ProdServerStart$.start(ProdServerStart.scala:52)
2015-07-05T06:24:10.456951+00:00 app[web.1]: at play.core.server.ProdServerStart$.main(ProdServerStart.scala:27)
2015-07-05T06:24:10.456994+00:00 app[web.1]: at play.core.server.ProdServerStart.main(ProdServerStart.scala)
2015-07-05T06:24:10.457407+00:00 app[web.1]: at com.zaxxer.hikari.pool.BaseHikariPool.addConnection(BaseHikariPool.java:441)
2015-07-05T06:24:10.457496+00:00 app[web.1]: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
2015-07-05T06:24:10.457369+00:00 app[web.1]: Caused by: java.sql.SQLException: JDBC4 Connection.isValid() method not supported, connection test query must be configured
2015-07-05T06:24:10.457602+00:00 app[web.1]: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2015-07-05T06:24:10.457451+00:00 app[web.1]: at com.zaxxer.hikari.pool.BaseHikariPool$1.run(BaseHikariPool.java:413)
2015-07-05T06:24:10.457681+00:00 app[web.1]: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
2015-07-05T06:24:10.457812+00:00 app[web.1]: at java.lang.Thread.run(Thread.java:745)
2015-07-05T06:24:10.457768+00:00 app[web.1]: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
2015-07-05T06:24:11.231007+00:00 heroku[web.1]: Process …
Run Code Online (Sandbox Code Playgroud) 为简化起见,假设我有三个表:
val postTable = TableQuery[Posts]
val postTagTable = TableQuery[PostTags]
val tagTable = TableQuery[Tags]
Run Code Online (Sandbox Code Playgroud)
一个帖子可以有多个标签,postTagTable
只包含关系.
现在我可以像这样查询帖子和标签:
val query = for {
post <- postTable
postTag <- postTagTable if post.id === postTag.postId
tag <- tagTable if postTag.tagId === tag.id
} yield (post, tag)
val postTags = db.run(query.result).map {
case result: Seq[(Post,Tag)] =>
result.groupBy(_._1).map {
case (post, postTagSeq) => (post, postTagSeq.map(_._2))
}
}
Run Code Online (Sandbox Code Playgroud)
哪个会给我一个Future[Seq[(Post, Seq(Tag))]]
.
到现在为止还挺好.
但是,如果我想为帖子添加分页呢?由于一个人Post
可以拥有Tags
上述查询的多个,我不知道查询中有多少行take
,以便得到,比方说,10 Posts
.
有没有人知道在一个查询中使用特定数量的帖子获得相同结果的好方法?
我实际上甚至不确定如何在没有嵌套查询的情况下在本机SQL中处理此问题,因此如果有人在该方向上有建议,我也很乐意听到它.
谢谢!
编辑 …
尽管文档说您可以编译更新,但是我无法让Slick 3.1编译更新,而将要更新的值传递到已编译的块中。
对于我的用例,我想找到一个具有给定键的行,其中停用为空,并将停用时间设置为新的时间戳。
我想做的显而易见的事情是:
private[this] lazy val updateDeactiveTime = Compiled { (settingName: Rep[String], time: Rep[Instant]) =>
settings
.filter { row => row.name === settingName && row.deactivatedAt.isEmpty }
.map { _.deactivatedAt }
.update(Some(time))
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这给了我一个update
不能接受的投诉Rep[Option[Instant]]
:它想要一个Option[Instant]
。
我了解Slick(不幸的是)不允许您在更新中使用动态计算的值。根据文档,限制操作之类的解决方法是使用ConstColumn[…]
。尽职尽责,我尝试传递a ConstColumn[Option[Instant]]
,希望会有一些隐式转换或扩展,但是我仍然抱怨它必须是文字Option[Instant]
。
当然,我有立即数,但是如果每次目标值更改时都必须重新编译更新,那么编译更新没有多大意义。
如果我使用a LiteralColumn[…]
,我可以打电话_.value
,但是Compiled
不会让我要求a LiteralColumn
。Compiled
也不允许我将参数设为time: Instant
。
我的数据库中有以下列,多数民众赞成是布尔值,但也接受NULL,因此true,false和NULL都是有效的:
def rtb = column[Option[Boolean]]("rtb")
Run Code Online (Sandbox Code Playgroud)
并从我要过滤的客户端中获取以下可选输入:
rtbFromClient: Option[Boolean] = ...
Run Code Online (Sandbox Code Playgroud)
我有以下内容(基于有关如何在光滑的查询中进行查询的答案:https : //stackoverflow.com/a/40888918/5300930):
val query = userTable.
filter(row =>
if (rtbFromClient.isDefined)
row.rtb.get === rtbFromClient.get
else
LiteralColumn(true)
)
Run Code Online (Sandbox Code Playgroud)
但是在代码运行时出现此错误:
Caught exception while computing default value for Rep[Option[_]].getOrElse -- This cannot be done lazily when the value is needed on the database side
Run Code Online (Sandbox Code Playgroud)
我认为可能是因为row.rtb.get在调用时抛出异常,因为db中的值为null,所以尝试将其更改为row.rtb.getOrElse(null)和row.rtb.getOrElse(None),但是这些都不起作用)
还尝试了以下方法:
if (rtbFromClient.isDefined) {
val query = query.filter(_.rtb.isDefined).filter(_.rtb.get === rtbFromClient.get)
}
Run Code Online (Sandbox Code Playgroud)
但这也会在运行时引发相同的错误:
Caught exception while computing default value for Rep[Option[_]].getOrElse -- This cannot be done lazily …
Run Code Online (Sandbox Code Playgroud) 我有一个带有不可为空的列的表:
class Users(tag: Tag) extends Table[User](tag, "users") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def surname = column[String]("surname")
}
Run Code Online (Sandbox Code Playgroud)
我只想更新一些列(如果不是None
):
def update(id: String, name: Option[String], surname: Option[String]) = {
(name, surname) match {
case (Some(n), Some(s)) => byId(id)
.map(l => (l.name, l.surname))
.update((n, s))
case (None, Some(s)) => byId(id)
.map(l => (l.surname))
.update(s)
case (Some(n),None) => byId(id)
.map(l => (l.name))
.update(n)
}
}
Run Code Online (Sandbox Code Playgroud)
有没有更优雅的方法可以做到这一点?如果有很多更新参数怎么办?
每当我收到给定id的更新请求时,我都会尝试更新DB表中的masterId和updatedDtTm列(我不想更新我的createdDtTm).以下是我的代码:
case class Master(id:Option[Long] = None,masterId:String,createdDtTm:Option[java.util.Date],
updatedDtTm:Option[java.util.Date])
/**
* This is my Slick Mapping table
* with the default projection
*/
`class MappingMaster(tag:Tag) extends
Table[Master](tag,"master") {
implicit val DateTimeColumnType = MappedColumnType.base[java.util.Date, java.sql.Timestamp](
{
ud => new Timestamp(ud.getTime)
}, {
sd => new java.util.Date(sd.getTime)
})
def id = column[Long]("id",O.PrimaryKey,O.AutoInc)
def masterId = column[String]("master_id")
def createdDtTm = column[java.util.Date]("created_dttm")
def updatedDtTm = column[java.util.Date]("updated_dttm")
def * = (id.? , masterId , createdDtTm.? , updatedDtTm.?) <>
((Master.apply _).tupled , Master.unapply _) }
/**
* Some …
Run Code Online (Sandbox Code Playgroud) 您能否向我解释由于模棱两可的隐式方法,我该如何转换MappedProjection
为ProvenShape
当前失败的方法?
我使用slick-pg支持jsonb
Postgres DB中的类型。
我有一个简单的案例类,我想存储为json,并且有ID列,其值来自案例类。
case class Topic(id: String, title: String)
class TopicRow(tag: Tag) extends Table[(String, Topic)](tag, Topic.tableName) {
def id = column[String]("id", O.PrimaryKey)
def json = column[Topic]("json")
def * = (id, json)
}
Run Code Online (Sandbox Code Playgroud)
在代码的前面,我在json和case类之间进行了转换
import spray.json._
implicit val TopicColumnType = MappedColumnType.base[Topic, JsValue ](
{ obj => obj.toJson }, { json => json.convertTo[Topic] }
)
Run Code Online (Sandbox Code Playgroud)
我不喜欢的TopicRow
是它映射到元组。我希望它像这样
class TopicRow(tag: Tag) extends Table[Topic](tag, Topic.tableName) {
def id = column[String]("id", O.PrimaryKey)
def json = …
Run Code Online (Sandbox Code Playgroud) 我是scala世界的新手(来自android世界),我用play-framework创建了scala项目,一切正常,我需要添加数据库,为此我决定选择光滑,但是当我试图添加时像这样的依赖
libraryDependencies ++= Seq(
"com.typesafe.slick" %% "slick" % "3.1.0",
"org.slf4j" % "slf4j-nop" % "1.6.4"
)
Run Code Online (Sandbox Code Playgroud)
我收到此错误日志
Error:Error while importing SBT project:<br/>...<br/><pre>[info] Resolving com.typesafe#jse_2.10;1.2.3 ...
[info] Resolving org.scala-sbt#run;0.13.15 ...
[info] Resolving org.scala-sbt.ivy#ivy;2.3.0-sbt-48dd0744422128446aee9ac31aa356ee203cc9f4 ...
[info] Resolving com.typesafe.play#play-exceptions;2.6.5 ...
[info] Resolving org.scala-sbt#test-interface;1.0 ...
[info] Resolving com.jcraft#jsch;0.1.50 ...
[info] Resolving org.scala-lang#scala-compiler;2.10.6 ...
[info] Resolving jline#jline;2.14.3 ...
[info] Resolving org.scala-sbt#compiler-ivy-integration;0.13.15 ...
[info] Resolving org.scala-sbt#incremental-compiler;0.13.15 ...
[info] Resolving org.scala-sbt#logic;0.13.15 ...
[info] Resolving com.typesafe#config;1.3.1 ...
[info] Resolving org.scala-sbt#main-settings;0.13.15 ...
[info] Resolving com.lightbend.play#play-file-watch_2.10;1.0.0 ...
[info] Resolving …
Run Code Online (Sandbox Code Playgroud) Writestream
Spark Structured Streaming 2.2.1中没有按顺序发生两个到同一个数据库接收器.请建议如何按顺序执行它们.
val deleteSink = ds1.writestream
.outputMode("update")
.foreach(mydbsink)
.start()
val UpsertSink = ds2.writestream
.outputMode("update")
.foreach(mydbsink)
.start()
deleteSink.awaitTermination()
UpsertSink.awaitTermination()
Run Code Online (Sandbox Code Playgroud)
使用上面的代码,deleteSink
之后执行UpsertSink
.
scala ×10
slick-3.0 ×10
slick ×5
apache-spark ×1
heroku ×1
hikaricp ×1
postgresql ×1
reflection ×1
sbt ×1
scala-2.11 ×1
sql ×1