scala - 如何抽象光滑表之间的列定义?

标签 scala generics slick

我正在尝试向现有灵活应用程序中的多个表添加新列。所有表中的列都是相同的:将客户端 ID 添加到表中,以便在所有查询中启用客户端过滤。但是,在某些情况下,此 id 是可选的:因此我需要使用现有查询来处理这两种情况。

当我尝试编写一些代码以使用新列在新客户端上进行筛选时,问题就出现了。我想编写一个方法来包装所有已修改表的表查询,并可选择在客户端上进行过滤,但是当我尝试编写一个方法来执行此操作时,slick 失败了。

我尝试在 slick 中添加一个扩展 Table 的抽象类来包装我想要添加新客户端列的表格

  abstract class ClientTable[T](tag: Tag, name: String) extends Table[T](tag,name)  {
    def client: Rep[Option[Int]]
  }

  class Feeds(tag: Tag) extends ClientTable[Feed](tag, "feeds") {
    def id: Rep[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc)

    def name: Rep[String] = column[String]("name")

    ...

    def client: Rep[Option[Int]] = column[Option[Int]]("client")

    private val list = id :: name :: ... :: client :: HNil

    def * : ProvenShape[Feed] = list.mappedWith(Generic[Feed])
  }

但是,这似乎根本不适用于 slick。

总的来说,我希望这个方法(或类似的方法)能够发挥作用:

  def tableView[T <: ClientTable[E], E] (tableQuery: TableQuery[E], clientId: Option[Int]) = {
    clientId match {
      case Some(id) => tableQuery.filter(_.client === id)
      case None => tableQuery
    }
  }
}

这样我就可以用 private val xTable = tableView(TableQuery[X], clientId) 替换查询中的 TableQuery 定义,然后希望不必更改我所有现有的查询。

最佳答案

没有什么比未解答的堆栈溢出问题更糟糕的了!因此,这就是我最终解决这个问题的方法。


我正在努力的方法最终是正确的,只是我的泛型略有错误。工作版本如下所示:

def tableView[T <: ClientTable[E], E <: ClientColumn](tableQuery: TableQuery[T], clientId: Option[Int]): Query[T, T#TableElementType, Seq] = {
    clientId match {
      case Some(id) => tableQuery.filter(_.client === id)
      case None => tableQuery
    }
  }

在表定义中,您需要使用具有 client 列的实现来扩展 Table 类型:

abstract class ClientTable[T](tag: Tag, name: String) extends Table[T](tag, name) {
  def client: Rep[Option[Int]] = column[Option[Int]]("client")
}

并使用将 client 字段添加到所有行案例类的特征来扩展行案例类

trait ClientColumn {
  def client: Option[Int]
}

case class Feed(id: Int = 0,
                name: String,
...
                client: Option[Int]) extends ClientColumn

现在,tableView 方法将按预期工作,尽管似乎仅在传递类型参数时,例如 val x = tableView[X, x](TableQuery[X], client) 因为 Scala 似乎无法推断这两个泛型参数的类型。

值得一提的是,我没有使用 Slick 来创建表或 ddl 语句,而是使用 Flyway。在这种情况下,将此方法与抽象类trait 结合使用可能不起作用。

无论怎样,祝以后找到这个问题和答案的人好运!

关于scala - 如何抽象光滑表之间的列定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56955313/

相关文章:

scala - 如何从光滑的查询创建类实例?

scala - 如何最好地处理Future.filter谓词不满足类型错误

scala - 在嵌套类型的伴随对象中查找隐式值

regex - 如何使用 Spark 读取自定义多行日志

java - 如何在Map.Entry中使用泛型方法参数?

c# - 如何在 C# 中使用动态键创建列表字典

scala - 如何从运行时参数指定 SLICK Query sortBy 列?

scala - Slick有缓存机制吗?

scala - Spark GraphX 聚合求和

java - Collection 类中的 toArray() 方法