【问题标题】:How I can insert case object as JSONB format via Doobie?如何通过 Doobie 将案例对象插入为 JSONB 格式?
【发布时间】:2021-08-19 16:11:16
【问题描述】:

我使用 scala 2.13 和 doobie 0.12.1

例如, 我有案例课

case class UserInfo(name: String, age: Int, hobbies: Vector[String])

我想在列信息中插入用户信息作为 jsonb

sql"""
        INSERT INTO users(
            id,
            info
            created_at,
        ) values (
            ${id},
            ${userInfo},
            ${createdAt},
        )
      """.update.run.transact(t)

在我的 DAO 中,我有隐含的 val

implicit val JsonbMeta: Meta[Json] = Meta
.Advanced.other[PGobject]("jsonb")
.timap[Json](jsonStr => parser.parse(jsonStr.getValue).leftMap[Json](err => throw err).merge)(json => {
  val o = new PGobject
  o.setType("jsonb")
  o.setValue(json.noSpaces)
  o
})

但我有编译异常

found   : ***.****.UserInfo
   [error]  required: doobie.syntax.SqlInterpolator.SingleFragment[_]; incompatible interpolation method sql
    [error]       sql"""
    [error]       ^

【问题讨论】:

    标签: postgresql scala jsonb doobie


    【解决方案1】:

    doobie-postgres-circe module 提供pgEncoderPutpgDecoderGet。有了这些,以及范围内的隐式循环EncoderDecoder,您就可以创建一个Meta[UserInfo]。那么您的示例插入应该可以工作。

    示例用法:

    // Given encoder & decoder (or you could import io.circe.generic.auto._)
    implicit encoder: io.circe.Encoder[UserInfo] = ???
    implicit decoder: io.circe.Decoder[UserInfo] = ???
    
    import doobie.postgres.circe.jsonb.implicits.{pgDecoderGet, pgEncoderPut}
    
    implicit val meta: Meta[UserInfo] = new Meta(pgDecoderGet, pgEncoderPut)
    
    

    【讨论】:

    • 谢谢!这对我来说是最正确的解决方案!
    【解决方案2】:

    您已经为 Json 类型定义了 Meta,但看起来您在插值字符串中使用了 UserInfo 的实例。尝试将对象转换为Json 并将其传递给sql

    // This assumes you're using Circe as your JSON library
    import io.circe._, io.circe.generic.semiauto._, io.circe.syntax._
    
    implicit val userInfoEncoder: Encoder[UserInfo] = deriveEncoder[UserInfo]
    
    val userInfo: UserInfo = UserInfo("John", 50, Vector("Scala"))
    val userInfoJson: Json = userInfo.asJson // requires Encoder[UserInfo]
    
    // and then, assuming that an implicit Meta[Json] is in scope
    sql"""INSERT INTO users(
                id,
                info
                created_at,
            ) values (
                ${id},
                ${userInfoJson}, -- instance of Json here
                ${createdAt},
            )"""
    

    【讨论】:

    • 尝试将 circe Json 类型插入 postgres json 列时出现错误。有任何想法吗? [error] found : io.circe.Json [error] required: doobie.syntax.SqlInterpolator.SingleFragment[_]
    • 我的代码 sn-p 不完整,它假定 Meta[Json] 的隐式实例在范围内。如果您在问题中定义一个隐含的 Meta[Json] 会有所帮助吗?此外,您可以考虑接受的答案中描述的方法,它需要的样板文件比我的少。
    • 我在隐式范围内确实有一个Meta[Json]。我尝试了接受的答案,但仍然遇到同样的错误。
    • 好的,我搞定了。它需要隐含的Meta[Json]Meta[UserInfo],doobie 才能识别 json 映射。
    猜你喜欢
    • 2020-01-11
    • 2021-07-21
    • 1970-01-01
    • 2017-03-09
    • 2020-07-24
    • 1970-01-01
    • 1970-01-01
    • 2018-05-12
    • 2017-06-13
    相关资源
    最近更新 更多