postgresql - 由于含糊不清的隐式,无法将 MappedProjection 转换为 ProvenShape

标签 postgresql scala slick implicit-conversion slick-3.0

能否请您向我解释一下如何将 MappedProjection 转换为 ProvenShape,目前由于含糊不清的隐含而失败?

我使用 slick-pg用于支持 Postgres 数据库中的 jsonb 类型。

我有一个简单的案例类,我想将其存储为 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)
}

在代码的前面,我在 json 和案例类之间进行了转换

import spray.json._
implicit val TopicColumnType = MappedColumnType.base[Topic, JsValue ](
  { obj => obj.toJson }, { json => json.convertTo[Topic] }
)

TopicRow 我不喜欢的是它映射到元组。我希望它是这样的

class TopicRow(tag: Tag) extends Table[Topic](tag, Topic.tableName) {

  def id = column[String]("id", O.PrimaryKey)
  def json = column[Topic]("json")

  val tupled: ((String, Topic)) => (Topic) = tu => tu._2
  val unapply: (Topic) => Option[(String, Topic)] = t => Option((t.id, t))
  def * = (id, json) <> (tupled, unapply)
}

编译失败

Error:(43, 22) type mismatch;
 found   : slick.lifted.MappedProjection[co.younetworks.medstream.server.models.db.Topic,(String, co.younetworks.medstream.server.models.db.Topic)]
 required: slick.lifted.ProvenShape[co.younetworks.medstream.server.models.db.Topic]

所以我像这样明确指定了转换的每一步

def * = {
  val shape: ProvenShape[Topic] = {
    val tupled: ((String, Topic)) => (Topic) = tu => tu._2
    val unapply: (Topic) => Option[(String, Topic)] = t => Option((t.id, t))
    val toToShapedValue: ToShapedValue[(Rep[String], Rep[Topic])] = anyToToShapedValue((id, json))
    val mappedProjection: MappedProjection[Topic, (String, Topic)] = toToShapedValue <>(tupled, unapply)
    ProvenShape.proveShapeOf(mappedProjection)
  }
  shape
}

这给了我错误

Error:(52, 31) ambiguous implicit values:
 both method mappedProjectionShape in object MappedProjection of type [Level >: slick.lifted.FlatShapeLevel <: slick.lifted.ShapeLevel, T, P]=> slick.lifted.Shape[Level,slick.lifted.MappedProjection[T,P],T,slick.lifted.MappedProjection[T,P]]
 and method repColumnShape in trait RepShapeImplicits of type [T, Level <: slick.lifted.ShapeLevel](implicit evidence$1: slick.ast.BaseTypedType[T])slick.lifted.Shape[Level,slick.lifted.Rep[T],T,slick.lifted.Rep[T]]
 match expected type slick.lifted.Shape[_ <: slick.lifted.FlatShapeLevel, slick.lifted.MappedProjection[co.younetworks.medstream.server.models.db.Topic,(String, co.younetworks.medstream.server.models.db.Topic)], U, _]
      ProvenShape.proveShapeOf(mappedProjection)
                              ^

我怀疑我将编译器与映射列的存在混淆了,但我不知道如何修复它。

最佳答案

好吧,隐式的显式规范很有帮助。虽然它看起来并不漂亮。

class TopicRow(tag: Tag) extends Table[Topic](tag, Topic.tableName) with JsonMarshallers {

  def id = column[String]("id", O.PrimaryKey)
  def json = column[Topic]("json")

  private val fromTuple : ((String, Topic)) => (Topic) = { case (_, value) => value }
  private val toTuple = (v : Topic) => Option((v.id, v))
  def * = ProvenShape.proveShapeOf((id, json) <> (fromTuple, toTuple))(MappedProjection.mappedProjectionShape)
}

如果有人知道如何让它短路,请告诉我。

关于postgresql - 由于含糊不清的隐式,无法将 MappedProjection 转换为 ProvenShape,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34366478/

相关文章:

自定义用户类型(枚举)的 Scala 光滑查询比较给出错误

scala - 如何使用 Play with Scala 和 Slick 从数据库中获取记录

sql - 在 Postgres 中使用自引用更新表会更新比预期更多的条目

scala - 使用 Scala 2.10 `to` 将列表转换为 SortedMap

java - 关闭后如何重新连接kafka生产者?

java - 如何在 Play 中使用 Java 类构建 Scala 表单

database - 如何在 Slick 3.1 中使用不支持的数据库

sql - 关于 SQL/Postgres 中聚合函数内部的问题

postgresql - 什么哈希算法最适合在 Postgres 中生成唯一 ID?

sql - 如何按 a、b 进行分组并返回 b 的 N 行集