用于多个 TableQuery 实例的 Scala Slick 单个过滤器
Scala Slick single filter for multiple TableQuery instances
我正在使用 Scala Slick-3.1.0 库。
如何制作一个通用的 Slick 过滤器函数,将 TableQuery 实例作为输入并对其进行相同的 slick 过滤器?
我有几个案例 classes(例如两个)代表存储在数据库中的数据。
有些字段是相同的,因此 classes 可能会扩展共同的祖先:
case class FirstData(symbol: String,
date: Timestamp,
firstField: Double)
case class SecondData(symbol: String,
date: Timestamp,
secondField: String)
他们每个人在数据库中都有自己的 SQL Table,并由单独的 Slick Table
class 表示。他们也有相同的主键:
class FirstDataTable(tag: Tag) extends Table[FirstData](tag, "firstData") {
def symbol = column[String]("symbol")
def date = column[Timestamp]("date")
def firstField= column[Double]("firstField")
def * = (symbol, date, firstField) <> ((FirstData.apply _).tupled, FirstData.unapply)
def pk = primaryKey("pk_firstData", (symbol, date))
}
class SecondDataTable(tag: Tag) extends Table[SecondData](tag, "secondData"){
def symbol = column[String]("symbol")
def date = column[Timestamp]("date")
def secondField= column[String]("secondField")
def * = (symbol, date, secondField) <> ((SecondData.apply _).tupled, SecondData.unapply)
def pk = primaryKey("pk_secondData", (symbol, date))
}
最后TableQuery
class是:
val firstDataTableQuery = TableQuery[FirstDataTable]
val secondDataTableQuery = TableQuery[SecondDataTable]
etc ...
如何制作一个通用的 Slick 过滤器查询函数,该函数将 firstDataTableQuery
或 secondDataTableQuery
作为参数并在输入时进行相同的 slick 查询。仅在它们的公共字段上过滤,或者以另一种方式在它们的 SQL Table 表示公共列上过滤。例如像这样:
def filter(genericTableQuery: TableQuery) = {
genericTableQuery.filter { data => dataFilterFunction(data.symbol)
}.filter(_.date >= someDate).sortBy(data => data.date.asc)
}
val firstTableResult = filter(firstDataTableQuery)
val seconfTableResult = filter(secondDataTableQuery)
etc ...
我看了这个题目,还是想不出解决办法:
如何使数据 table 类 扩展一个共同特征,进而扩展数据 类 的一个共同特征,例如:
trait Data {
def symbol: String
def date: Timestamp
}
// make FirstData and SecondData extend the above trait
trait GenericDataTable extends Data {
def symbol: Rep[String]
def date: Rep[Timestamp]
def pk: PrimaryKey
}
class FirstDataTable(tag: Tag) extends Table[FirstData](tag, "firstData") with GenericDataTable {
// ...
然后:
def filter[T <: GenericDataTable](genericTableQuery: TableQuery[T]) = // ...
invariant,非常感谢。你给我指出了正确的方向。我稍微修改了你的答案,一切正常)
特征:
trait Data {
def symbol: String
def date: Timestamp
}
trait GenericDataTable[T <: Data] extends Table[T] {
def symbol: Rep[String]
def date: Rep[Timestamp]
def pk: PrimaryKey
}
FirstData 和 FirstDataTable 类 看起来像这样:
case class FirstData(
symbol: String,
date: Timestamp,
firstField: Double) extends Data
class FirstDataTable(tag: Tag) extends Table[FirstData(tag,"firstData")
with GenericDataTable[FirstData] {
def symbol = column[String]("symbol")
def date = column[Timestamp]("date")
def firstField= column[Double]("firstField")
def * = (symbol, date, firstField) <> ((FirstData.apply _).tupled, FirstData.unapply)
def pk = primaryKey("pk_firstData", (symbol, date))
}
最终函数如下所示:
private def filter[M <: Data, T <: GenericDataTable[M]] (genericTableQuery: TableQuery[T]) = {
genericTableQuery.filter { data => dataFilterFunction(data.symbol)}.
filter(_.date >= someDate).sortBy(data => data.date.asc)
}
我正在使用 Scala Slick-3.1.0 库。
如何制作一个通用的 Slick 过滤器函数,将 TableQuery 实例作为输入并对其进行相同的 slick 过滤器?
我有几个案例 classes(例如两个)代表存储在数据库中的数据。 有些字段是相同的,因此 classes 可能会扩展共同的祖先:
case class FirstData(symbol: String,
date: Timestamp,
firstField: Double)
case class SecondData(symbol: String,
date: Timestamp,
secondField: String)
他们每个人在数据库中都有自己的 SQL Table,并由单独的 Slick Table
class 表示。他们也有相同的主键:
class FirstDataTable(tag: Tag) extends Table[FirstData](tag, "firstData") {
def symbol = column[String]("symbol")
def date = column[Timestamp]("date")
def firstField= column[Double]("firstField")
def * = (symbol, date, firstField) <> ((FirstData.apply _).tupled, FirstData.unapply)
def pk = primaryKey("pk_firstData", (symbol, date))
}
class SecondDataTable(tag: Tag) extends Table[SecondData](tag, "secondData"){
def symbol = column[String]("symbol")
def date = column[Timestamp]("date")
def secondField= column[String]("secondField")
def * = (symbol, date, secondField) <> ((SecondData.apply _).tupled, SecondData.unapply)
def pk = primaryKey("pk_secondData", (symbol, date))
}
最后TableQuery
class是:
val firstDataTableQuery = TableQuery[FirstDataTable]
val secondDataTableQuery = TableQuery[SecondDataTable]
etc ...
如何制作一个通用的 Slick 过滤器查询函数,该函数将 firstDataTableQuery
或 secondDataTableQuery
作为参数并在输入时进行相同的 slick 查询。仅在它们的公共字段上过滤,或者以另一种方式在它们的 SQL Table 表示公共列上过滤。例如像这样:
def filter(genericTableQuery: TableQuery) = {
genericTableQuery.filter { data => dataFilterFunction(data.symbol)
}.filter(_.date >= someDate).sortBy(data => data.date.asc)
}
val firstTableResult = filter(firstDataTableQuery)
val seconfTableResult = filter(secondDataTableQuery)
etc ...
我看了这个题目,还是想不出解决办法:
如何使数据 table 类 扩展一个共同特征,进而扩展数据 类 的一个共同特征,例如:
trait Data {
def symbol: String
def date: Timestamp
}
// make FirstData and SecondData extend the above trait
trait GenericDataTable extends Data {
def symbol: Rep[String]
def date: Rep[Timestamp]
def pk: PrimaryKey
}
class FirstDataTable(tag: Tag) extends Table[FirstData](tag, "firstData") with GenericDataTable {
// ...
然后:
def filter[T <: GenericDataTable](genericTableQuery: TableQuery[T]) = // ...
invariant,非常感谢。你给我指出了正确的方向。我稍微修改了你的答案,一切正常)
特征:
trait Data {
def symbol: String
def date: Timestamp
}
trait GenericDataTable[T <: Data] extends Table[T] {
def symbol: Rep[String]
def date: Rep[Timestamp]
def pk: PrimaryKey
}
FirstData 和 FirstDataTable 类 看起来像这样:
case class FirstData(
symbol: String,
date: Timestamp,
firstField: Double) extends Data
class FirstDataTable(tag: Tag) extends Table[FirstData(tag,"firstData")
with GenericDataTable[FirstData] {
def symbol = column[String]("symbol")
def date = column[Timestamp]("date")
def firstField= column[Double]("firstField")
def * = (symbol, date, firstField) <> ((FirstData.apply _).tupled, FirstData.unapply)
def pk = primaryKey("pk_firstData", (symbol, date))
}
最终函数如下所示:
private def filter[M <: Data, T <: GenericDataTable[M]] (genericTableQuery: TableQuery[T]) = {
genericTableQuery.filter { data => dataFilterFunction(data.symbol)}.
filter(_.date >= someDate).sortBy(data => data.date.asc)
}