1

我正在开发一个基本的工作板应用程序以进行练习,并且在尝试编译我的 Scala 代码时出现以下错误。

[warn] insecure HTTP request is deprecated 'http://repo.typesafe.com/typesafe/releases/'; switch to HTTPS or opt-in as ("Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/").withAllowInsecureProtocol(true)
[info] Compiling 8 Scala sources to /Users/ryanmcavoy/Code/job-board/target/scala-2.11/classes ...
[error] /Users/ryanmcavoy/Code/job-board/src/main/scala/io/github/jobboard/database/JobQueries.scala:26:5: Could not find or construct Param[shapeless.::[String,shapeless.::[io.github.jobboard.model.JobPostDetails,shapeless.HNil]]].
[error] Ensure that this type is an atomic type with an Meta instance in scope, or is an HList whose members
[error] have Meta instances in scope. You can usually diagnose this problem by trying to summon the Meta
[error] instance for each element in the REPL. See the FAQ in the Book of Doobie for more hints.
[error]     sql"""
[error]     ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed

似乎在抱怨以下方法

  def insert(jobPost: JobPost): doobie.Update0 = {
    sql"""
         |INSERT INTO jobs (
         |  id,
         |  details
         |)
         |VALUES (
         |  ${jobPost.id},
         |  ${jobPost.details}
         |)
        """.stripMargin
      .update
  }

我在这里查看了文档:https ://tpolecat.github.io/doobie-0.2.3/15-FAQ.html但无法弄清楚。

有关其他信息,我将包括以下内容:

case class JobPost(id: String, details: JobPostDetails)

case class JobPostDetails(title: String, description: String, salary: Double, employmentType: String, employer: String)
    def createTable: doobie.Update0 = {
      sql"""
           |CREATE TABLE IF NOT EXISTS jobs (
           |  id UUID PRIMARY KEY,
           |  details JSON NOT NULL
           |)
       """.stripMargin
        .update
    }
4

1 回答 1

1

在您的情况下,Doobie 不知道如何序列JobPostDetails化为 Postgres 数据库上的 JSON 列。

默认情况下,Doobie 不知道如何将案例类更改为 JSON。可以说,在 scala 中序列化 JSON 的最流行的库是 circe。您必须在build.sbtfor circe 和 circe-Postgres-doobie 集成中添加其他依赖项。

"org.tpolecat" %% "doobie-postgres" % "0.8.8"
"org.tpolecat" %% "doobie-postgres-circe" % "0.8.8"
"io.circe" %% "circe-core" % "0.13.0"

然后,您应该在 的伴随对象中创建、和类型类Encoder的实例:DecoderPutGetJobPostDetails

import io.circe.{ Decoder, Encoder }
import io.circe.generic.semiauto.{ deriveDecoder, deriveEncoder }
import doobie.postgres.circe.json.implicits._
import doobie._
import io.circe.syntax._

case class JobPostDetails(title: String, description: String, salary: Double, employmentType: String, employer: String)

object JobPostDetails {

  //for decoding json into JobPostDetails
  implicit val circeDecoder: Decoder[JobPostDetails] =
    deriveDecoder[JobPostDetails]

  //for encoding JobPostDetails into json
  implicit val circeEncoder: Encoder[JobPostDetails] =
    deriveEncoder[JobPostDetails]

  //tells doobie to put JobPostDetails as json to details column
  implicit val put: Put[JobPostDetails] =
    Put[Json].contramap(_.asJson) 

  //tells doobie how to read JobPostDetails from json column
  implicit val get: Get[JobPostDetails] =
    Get[Json].temap(_.as[JobPostDetails].leftMap(_.show)) 
}

之后,您应该可以保存JobPost.

于 2020-08-07T09:49:38.077 回答