如何抽象光滑表之间的列定义?
How to abstract a column definition between slick tables?
我正在尝试向现有 slick 应用程序中的多个 table 添加一个新列。该列在所有 table 中都是相同的:将客户端 ID 添加到 table 以启用我们所有查询中的客户端过滤。然而,在某些情况下,这个 id 是可选的:因此我需要使用我们现有的查询来处理这两种情况。
当我尝试编写一些代码以使用新列在新客户端上进行筛选时,问题就来了。我想编写一个方法来包装所有修改后的 table 的 table 查询,并可选择在客户端上进行过滤,但是当我尝试编写一个方法来执行此操作时,slick 失败了。
我已经尝试添加一个摘要 class 扩展 Table
以巧妙地包裹 tables 我想添加新客户列的地方
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
}
}
在 table 定义中,您需要使用具有 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 来创建 table 或 ddl 语句,而是使用 flyway。在这种情况下,将此方法与 abstract class
和 trait
一起使用可能不起作用。
祝以后找到这个问题和答案的人好运!
我正在尝试向现有 slick 应用程序中的多个 table 添加一个新列。该列在所有 table 中都是相同的:将客户端 ID 添加到 table 以启用我们所有查询中的客户端过滤。然而,在某些情况下,这个 id 是可选的:因此我需要使用我们现有的查询来处理这两种情况。
当我尝试编写一些代码以使用新列在新客户端上进行筛选时,问题就来了。我想编写一个方法来包装所有修改后的 table 的 table 查询,并可选择在客户端上进行过滤,但是当我尝试编写一个方法来执行此操作时,slick 失败了。
我已经尝试添加一个摘要 class 扩展 Table
以巧妙地包裹 tables 我想添加新客户列的地方
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
}
}
在 table 定义中,您需要使用具有 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 来创建 table 或 ddl 语句,而是使用 flyway。在这种情况下,将此方法与 abstract class
和 trait
一起使用可能不起作用。
祝以后找到这个问题和答案的人好运!