例如,我有这个案例类:
case class User(
var identityId: IdentityId, //Its a user created class
var firstName: String,
var lastName: String,
var fullName: String,
var email: Option[String],
var avatarUrl: Option[String],
var authMethod: AuthenticationMethod,
var oAuth1Info: Option[OAuth1Info] = None,
var oAuth2Info: Option[OAuth2Info] = None,
var passwordInfo: Option[PasswordInfo] = None) extends Identity {
def this() = this(null, "", "", "", None, None, null, None, None, None)
}
Run Code Online (Sandbox Code Playgroud)
它实际上是一个secSecocial标识,现在identityId是一个case类的对象:
case class IdentityId(
var userId:String,
var providerId:String
)
Run Code Online (Sandbox Code Playgroud)
那么如何为像这样的情况创建一个投影类?如果我必须创建一个类似String的投影类数据类型,那么它本来就没有问题但是用户定义的对象和类呢?
我正在尝试为Slick表创建一个类型安全的动态DSL,但不知道如何实现这一点.
用户可以通过以form/json格式发送过滤器将过滤器发布到服务器,我需要构建一个带有所有这些的Slick查询.
所以基本上这意味着将表示我的过滤器的Scala案例类转换为Slick查询.
似乎"谓词"可以有3种不同的形状.我见过这个特质CanBeQueryCondition.我可以折叠这些不同的形状吗?
我已经看过扩展方法&&,||并且知道这与此有关但我只是不知道该怎么做.
基本上,我有一个谓词列表,它采用以下类型:
(PatientTable) => Column[Option[Boolean]]
Run Code Online (Sandbox Code Playgroud)
要么
(PatientTable) => Column[Boolean]
Run Code Online (Sandbox Code Playgroud)
对我来说问题是,对于所有3种不同的类型都没有单一的超类型CanBeQueryCondition,所以我真的不知道如何将谓词折叠&&为一次添加到列表中这些不同形状的谓词采用非常类型List[(PatientTable) => Column[_ >: Boolean with Option[Boolean]]].
另外,我不确定什么可以被认为是Slick中的谓词.可组合谓词似乎是Column[Boolean],但实际上该filter方法只接受类型的参数(PatientTable) => Column[Boolean]
这个问题与另一个问题有关.我也尝试使用joinLeft对查询进行排序,但是在光滑的3.0.0中.随着Option Rep被自动解除,我将如何做同样的事情?:
def list(filter: String, orderBy: Int):Future[Seq[(Computer, Option[Company])]] = {
val initialQuery = for {
(computer, company) <- Computer.filter(_.name like filter) leftJoin
Company on (_.companyId === _.id)
} yield (computer, company)
val sortedQuery = orderBy match {
case 2 => initialQuery.sortBy(_._1.name) //Works ok, column from a primary table
case 3 => initialQuery.sortBy(_._2.map(_.name)) //could not find implicit value for parameter ol: slick.lifted.OptionLift[slick.lifted.ColumnOrdered[String],slick.lifted.Rep[Option[QO]]]
}
db.run(sortedQuery.result)
}
Run Code Online (Sandbox Code Playgroud)
谢谢,
过去,我使用Slick访问服务器中的Vertica数据库.我最近将我的Slick版本从2.0升级到3.1.自升级以来,我遇到了一个错误(下面的堆栈跟踪).该错误表示无法找到光滑的驱动程序.
根据 Slick 3.2.1文档,"可以使用缩减的功能集立即访问其他SQL数据库".
我想知道的是 - 是否仍然可以使用光滑直接支持的"其他"类型的数据库?如果是这样,怎么样?
我的数据库配置是:
slick.dbs.default.driver="slick.driver.JdbcDriver"
slick.dbs.default.db.driver="com.vertica.jdbc.Driver"
slick.dbs.default.db.url=${some.url}
slick.dbs.default.db.user=${some.user}
slick.dbs.default.db.password=${some.pw}
Run Code Online (Sandbox Code Playgroud)
请注意,由于此Stack Overflow响应,我还尝试了以下各项来替换配置中的第一行:
slick.dbs.default.driver="slick.driver.JdbcDriver$"
slick.dbs.default.driver="slick.driver.JdbcDriver$class"
slick.dbs.default.driver=slick.driver.JdbcDriver
Run Code Online (Sandbox Code Playgroud)
我也有我的sbt文件:
libraryDependencies ++= Seq(
"com.vertica" % "vertica-jdbc" % "7.0.1",
"com.typesafe.play" %% "play-slick" % "2.0.0")
Run Code Online (Sandbox Code Playgroud)
请注意,Play-slick使用光滑的3.1.0.
完整堆栈跟踪:
[ERROR] [10/07/2016 16:43:52.336] [p.a.d.s.DefaultSlickApi] [*] Failed to create Slick database config for key default.
slick.SlickException: Error getting instance of Slick driver "slick.driver.JdbcDriver"
at slick.backend.DatabaseConfig$.forConfig(DatabaseConfig.scala:65)
at play.api.db.slick.DefaultSlickApi$DatabaseConfigFactory.create(SlickApi.scala:89)
at play.api.db.slick.DefaultSlickApi$DatabaseConfigFactory.get$lzycompute(SlickApi.scala:81)
at play.api.db.slick.DefaultSlickApi$DatabaseConfigFactory.get(SlickApi.scala:80)
at play.api.db.slick.DefaultSlickApi.dbConfig(SlickApi.scala:66)
at play.api.db.slick.NamedDatabaseConfigProvider$$anon$1.get(SlickModule.scala:59)
at utils.liger.DimensionMapper.<init>(DimensionMapper.scala:32)
at utils.liger.DimensionMapper$$FastClassByGuice$$1320fe73.newInstance(<generated>)
at com.google.inject.internal.cglib.reflect.$FastConstructor.newInstance(FastConstructor.java:40)
at com.google.inject.internal.DefaultConstructionProxyFactory$1.newInstance(DefaultConstructionProxyFactory.java:61)
at …Run Code Online (Sandbox Code Playgroud) 为了让scalatest中有一个数据库可用,我使用这个SO问题PlaySpec启发的默认扩展:
trait ResetDbSpec extends PlaySpec with BeforeAndAfterAll {
lazy val appBuilder = new GuiceApplicationBuilder()
lazy val injector = appBuilder.injector()
lazy val databaseApi = injector.instanceOf[DBApi]
override def beforeAll() = {
Evolutions.applyEvolutions(databaseApi.database("default"))
}
override def afterAll() = {
Evolutions.cleanupEvolutions(databaseApi.database("default"))
databaseApi.database("default").shutdown()
}
}
Run Code Online (Sandbox Code Playgroud)
它在套件启动时应用数据库演进,并在套件结束时恢复它们.然后测试看起来像
class ProjectsSpec extends ResetDbSpec with OneAppPerSuite { ...
Run Code Online (Sandbox Code Playgroud)
在添加了更多这样的测试之后,我遇到了一些问题,当我单独运行它们时,某些测试会成功,但是会出现此错误:
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:数据源拒绝建立连接,来自服务器的消息:"连接太多"
从上面的代码可以看出,我试图添加该行
databaseApi.database("default").shutdown()
Run Code Online (Sandbox Code Playgroud)
在afterAll()减轻这一点,但它没有任何效果.我试图不并行运行测试,但也没有效果.我在哪里打开数据库连接而不关闭它们,我应该在哪里打电话shutdown()?
NB我使用Play 2.5.10和Slick 3.1.
阅读Play-Slick DBAction代码,我认为此代码可能包含竞争条件:
object DBAction{
// snip
def apply(r: (RequestWithDbSession) => Result)(implicit app:Application) = {
Action { implicit request =>
AsyncResult {
DB.withSession{ s:scala.slick.session.Session =>
Future(r( RequestWithDbSession(request,s) ))(executionContext)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
该函数r在将来withSession返回Future [Result]并调用之后运行session.close().这段代码中是否存在竞争条件?
我正在使用Play Framework(2.3.1)和Slick(play-slick版本0.8.0-M1)和MySQL数据库(5.5.28).
我的一个查询导致MySQLSyntaxErrorException:
Preparing statement: select x2."id", x2."course_id", x2."trainee_id", x2."transaction_id" from "trainee_grouptraining_GroupBooking" x2 where x2."course_id" = 1
Run Code Online (Sandbox Code Playgroud)
问题似乎是双引号,因为其他查询工作得很好,他们使用单引号,如下所示:
Preparing statement: select x2.`id`, x2.`courseLanguage`, x2.`date`, x2.`description`, x2.`duration`, x2.`kind`, x2.`maxParticipants`, x2.`name`, x2.`courseType_id`, x2.`trainer_id` from `Course` x2 where x2.`id` = 1
Run Code Online (Sandbox Code Playgroud)
我该怎么办?
我正在尝试使用 slick 和 postgres 设置一个简单的 play 2.5 应用程序,但似乎无法克服错误。
我得到的错误是
[error] p.a.d.s.DefaultSlickApi - Failed to create Slick database config for key default.
slick.SlickException: Error getting instance of profile "slick.jdbc.PostgresProfile"
...
Caused by: java.lang.InstantiationException: slick.jdbc.PostgresProfile
...
Caused by: java.lang.NoSuchMethodException: slick.jdbc.PostgresProfile.<init>()
...
Run Code Online (Sandbox Code Playgroud)
我有以下内容 application.conf
slick.dbs.default {
driver = "slick.jdbc.PostgresProfile"
db = {
driver = "org.postgresql.Driver"
user = postgres
host = localhost
port = 5432
password = ""
host = ${?EVENTUAL_DB_HOST}
port = ${?EVENTUAL_DB_PORT}
user = ${?EVENTUAL_DB_USER}
password = ${?EVENTUAL_DB_PW}
url = "jdbc:postgresql://"${slick.dbs.default.db.host}":"${slick.dbs.default.db.port}"/"${slick.dbs.default.db.user}
} …Run Code Online (Sandbox Code Playgroud) 我有一个简单的方法来使用Sclick plain SQL方法从数据库中检索用户:
object Data {
implicit val getListStringResult = GetResult[List[String]] (
prs => (1 to prs.numColumns).map(_ => prs.nextString).toList
)
def getUser(id: Int): Option[List[String]] = DB.withSession {
sql"""SELECT * FROM "user" WHERE "id" = $id""".as[List[String]].firstOption
}
}
Run Code Online (Sandbox Code Playgroud)
结果是List[String]但我希望它是Map[String, String]- 列名和值对映射.这可能吗?如果是这样,怎么样?
我的堆栈是Play Framework 2.2.1,Slick 1.0.1,Scala 2.10.3,Java 8 64bit
我在dev和prod模式下使用(成功)flyway-play插件.我也想在测试模式下使用它.文档说,它在测试模式下自动运行迁移.
我使用scala测试,我的测试用包裹在假的应用程序中
val fakeApplication = FakeApplication(additionalConfiguration = Map(
"db.default.driver"->"org.h2.Driver",
"db.default.url"->"jdbc:h2:mem:test;MODE=MySQL;DB_CLOSE_DELAY=-1;",
"db.default.user"->"",
"db.default.password"->""
))
Run Code Online (Sandbox Code Playgroud)
运行测试用例时,自动迁移失败并显示"Schema public not found":
[info] com.googlecode.flyway.core.command.FlywaySqlScriptException: Error executing statement at line 17: CREATE TABLE "public"."schema_version" (
[info] "version_rank" INT NOT NULL,
[info] "installed_rank" INT NOT NULL,
[info] "version" VARCHAR(50) NOT NULL,
[info] "description" VARCHAR(200) NOT NULL,
[info] "type" VARCHAR(20) NOT NULL,
[info] "script" VARCHAR(1000) NOT NULL,
[info] "checksum" INT,
[info] "installed_by" VARCHAR(100) NOT NULL,
[info] "installed_on" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
[info] "execution_time" INT NOT NULL,
[info] …Run Code Online (Sandbox Code Playgroud) 我试图在播放框架中使用光滑,但即使是最简单的例子也在苦苦挣扎.
这是我的代码:
case class Account (
id: Int,
email: String,
password: String,
permission: String
)
class Accounts(tag: Tag) extends Table[Account](tag, "account") {
def id = column[Int]("id")
def email = column[String]("email")
def password = column[String]("password")
def permission = column[String]("permission")
def * = (id, email, password, permission)
}
Run Code Online (Sandbox Code Playgroud)
当我编译这个时,我收到以下错误:
play.PlayExceptions$CompilationException: Compilation error[No matching Shape found.
Slick does not know how to map the given types.
Possible causes: T in Table[T] does not match your * projection. Or you use an unsupported type …Run Code Online (Sandbox Code Playgroud) 我Json在 MySql 中有一个类型列,我正在使用带有 Slick 的 Scala。我如何Json通过 Slick为Column提供支持。
class SampleTable(tag: Tag) extends Table[(String, ??)](tag, "test") {
override def * : ProvenShape[NodeReference] = (name, data)
def name: Rep[String] = column[String]("name", O.PrimaryKey)
def Data: Rep[??] = column[??]("data", O.PrimaryKey)
}
Run Code Online (Sandbox Code Playgroud)
任何帮助将不胜感激。提前致谢
这是我试图优化的代码:
object UserRepo
{
val users = TableQuery[Users]
val dbName = "db"
lazy val queryAllUsers = for (user <- users) yield user
type UserRow = (Int, String, String, String)
def getAll() : Future[ Seq[UserRow] ] =
{
val db = Database.forConfig( dbName )
val f: Future[Seq[UserRow]] = db.run( queryAllUsers.result )
f.onComplete {
case Success(_) => { db.close() }
case Failure(_) => { db.close() }
}
f
}
}
Run Code Online (Sandbox Code Playgroud)
我将对数据库进行多次查询,我试图在创建数据库连接的地方删除字符串。是否有任何执行上下文可以用来显式关闭连接?这样代码看起来会更简洁?
是否可以选择在 Future.onComplete 范围内使用数据库连接?
谢谢