【问题标题】:play slick updating enumeration column玩光滑的更新枚举列
【发布时间】:2023-04-04 02:32:02
【问题描述】:

我无法弄清楚如何使用 play-slick 更新具有类型枚举的列。

这是我的枚举和案例类:

object TestStatus extends Enumeration {
  type TestStatus = Value
  val Status1 = Value("Status1")
}
case class Test (
  id: String,
  status: TestStatus
)

和表映射:

class Tests(tag: Tag) extends Table[Test](tag, "tests") {
  implicit val statusColumn = MappedColumnType.base[TestStatus, String](_.toString, TestStatus.withName)
  override def * = (id, status) <> ((Test.apply _).tupled, Test.unapply)
  val id = column[String]("id", 0.PrimaryKey)
  val status = column[TestStatus]("status")
}

当我尝试更新测试行时,我收到错误:

object TestQueries extends TableQuery[Tests](new Tests(_)) {
  def updateStatus(id: String, newStatus: TestStatus) = {
    TestQueries.filter(_.id === id).map(_.status).update(newStatus)
  }
}

[error] Slick does not know how to map the given types.
[error] Possible causes: T in Table[T] does not match your * projection,
[error]  you use an unsupported type in a Query (e.g. scala List),
[error]  or you forgot to import a driver api into scope.
[error]   Required level: slick.lifted.FlatShapeLevel
[error]      Source type: slick.lifted.Rep[models.TestStatus.Value]
[error]    Unpacked type: T
[error]      Packed type: G
[error]     TestQueries.filter(_.id === id).map(_.status).update(newStatus)
[error]                                        ^

IntelliJ 显示TestQueries.filter(_.id === id).map(_.status) 的类型为Query[Nothing, Nothing, Seq],这让我认为问题出在特定列而不是更新函数上。

使用相同的结构更新 id 可以正常工作。

【问题讨论】:

  • 似乎只有Tests 类具有TestStatus 的隐式列映射。您能否澄清TestQueries 在范围内是否也有正确的列映射?只是为了实验,尝试在 TestQueries 中复制 statusColumn 值并检查它是否编译。
  • @AdamBat 我的代码有点不清楚,但我尝试将列映射复制到各种范围:TestStatus 对象级别以及TestQueries 级别,所有结果都相同。
  • 您能否提供具有复制问题的存储库?我临时复制了您的代码并得到了相同的编译器错误。就像我在上面的评论中建议的那样,在TestQueries 中复制TestStatus 列映射有助于解决问题。这是我的要点,展示了我所做的一切:gist.github.com/Dasiu/ae4fa9bfa9077569e5e07a02aa1493f0

标签: scala playframework slick play-slick


【解决方案1】:

您需要定义TestStatus.Value的自定义列类型。这就是 slick 允许您通过将其映射到已支持的类型来构建自定义列类型的方式:

implicit def testStatCT: BaseTypedType[TestStatus.Value] = 
  MappedColumnType.base[TestStatus.Value, String](
    enum => enum.toString, str => TestStatus.withName(str)
  )

只要隐式解决方案(例如您的示例中的解决方案)失败(或更好地在 TestStatus 对象中定义,以便它始终可用),就需要导入此隐式解决方案,这样 slick 可以有证据证明 TestStatus.Value 是 @ 987654326@ 这基本上只是意味着某些东西是受支持的列类型。

如需进一步了解列映射,您可以查看Slick Documentation

【讨论】:

    猜你喜欢
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多