gpt4 book ai didi

scala - Slick 3.1-将列的子集作为案例类检索

转载 作者:行者123 更新时间:2023-12-03 14:19:38 26 4
gpt4 key购买 nike

我正在使用Slick 3.1.1,问题是在某些情况下我想忽略一些很重的列,但仍将这些列的子集作为案例类实现。

考虑以下表定义:

class AuditResultTable(tag: Tag) extends Table[AuditResult](tag, AuditResultTableName) {
def auditResultId: Rep[Long] = column[Long]("AuditResultId", O.PrimaryKey, O.AutoInc)
def processorId: Rep[Long] = column[Long]("ProcessorId")
def dispatchedTimestamp: Rep[Timestamp] = column[Timestamp]("DispatchedTimestamp", O.SqlType("timestamp(2)"))
def SystemAOutput: Rep[Array[Byte]] = column[Array[Byte]]("SystemAOutput", O.SqlType("LONGBLOB"))
def SystemBOutput: Rep[Array[Byte]] = column[Array[Byte]]("SystemBOutput", O.SqlType("LONGBLOB"))
def isSuccessful: Rep[Boolean] = column[Boolean]("IsSuccessful")


def * : ProvenShape[AuditResult] = (processorId, dispatchedTimestamp, systemAOutput, systemBOutput, isSuccessful, auditResultId) <>
(AuditResult.tupled, AuditResult.unapply)

}

val auditResults = TableQuery[AuditResultTable]


对应的案例类:

case class AuditResult (
ProcessorId: Long,
DispatchedTimestamp: Timestamp,
SystemAOutput: Array[Byte],
SystemBOutput: Array[Byte],
IsSuccessful: Boolean,
AuditResultId: Long = 0L
)


最后是数据访问查询:

def getRecentFailedAuditsQuery(): Query[AuditResultTable, AuditResult, Seq] = {
auditResults.filterNot(r => r.isSuccessful)
}


我考虑并研究了 in this (outdated) answer和其他选项:


与默认的投影不同,它的投影与 AuditResult的浅色版本(例如 AuditResultLight)相对应,而忽略了这些列-尽管尽我最大的努力,我仍然无法完成这项工作-我觉得这应该是正确的方法-投影完成后,仍然出现Slick错误“找不到匹配的Shape。 Slick不知道如何映射给定的类型”
用抽象的 AuditResultTableBase类和派生自其的两个类构建一个类层次结构-一个添加“重载”列,一个不添加“重载”列,分别具有各自的默认投影类和案例类。这很好用,但是这种方法似乎是错误的,并且需要相对较大的代码更改才能做到这一点。
实现元组而不是案例类-这当然可以,但是我希望我的数据访问层是强类型的。


对于此问题,Slick 3.1的惯用/最佳实践是什么?我可以为此使用自定义投影吗?如果是这样,对于此特定示例/查询, SystemAOutputSystemBOutput是我要忽略的较重的列,会是什么样?

最佳答案

我有类似的问题!您必须定义形状!在documentation的帮助下,我设法通过“轻量级”案例类来实现该方法。

首先,定义更简单的类:

case class AuditResultLight(
ProcessorId: Long,
DispatchedTimestamp: Timestamp,
IsSuccessful: Boolean,
AuditResultId: Long = 0L
)


然后,您需要创建案例类的提升版本:

case class AuditResultLightLifted(
ProcessorId: Rep[Long],
DispatchedTimestamp: Rep[Timestamp],
IsSuccessful: Rep[Boolean],
AuditResultId: Rep[Long]
)


另外,您需要一个隐式对象(Shape)来告诉滑模如何将一个映射到另一个:

implicit object AuditResultLightShape 
extends CaseClassShape(AuditResultLightLifted.tupled, AuditResultLight.tupled)


现在,您可以定义一个返回AuditResultLight的查询(不完全是一个投影,但据我了解它的工作原理类似):

val auditResultsLight = auditResults.map(r => AuditResultLightLifted(r.ProcessorId, r.DispatchedTimestamp, r.IsSuccessful, r.AuditResultId))  


然后,您可以定义以轻形式返回失败审核的函数:

def getRecentFailedAuditsQuery(): Query[AuditResultTable, AuditResultLight, Seq] = {
auditResultsLight.filterNot(r => r.isSuccessful)
}


要点,代码为: https://gist.github.com/wjur/93712a51d392d181ab7fc2408e4ce48b

代码可以编译并执行,但就我而言,问题是我的IDE(IntelliJ)报告了 Query[Nothing, Nothing, scala.Seq]auditResultsLight类型。每当使用 auditResultsLight并在查询中引用 AuditResultLight字段时,都会出现语法错误。但是,因此,最终,我决定使用您建议的第二种方法(带有抽象表的方法)。几乎相同数量的代码,但是具有IDE支持。

关于scala - Slick 3.1-将列的子集作为案例类检索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39781193/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com