我正在使用slick 3.0。我只是想将一些数据库设置代码集中到一个特征中。
以下是我所拥有的:
import slick.driver.H2Driver.api._
import scala.concurrent.Await
import scala.concurrent.duration.Duration
object EventFixtures {
val table = TableQuery[EventsTable]
val data = Seq(...)
def insertFixtures(db: Database): Int = {
Await.result(db.run(table.schema.create), Duration.Inf)
Await.result(db.run(table ++= data), Duration.Inf).get
}
}
我已经举起并将其转移到一个特性:
import slick.driver.H2Driver.api._
import scala.concurrent.Await
import scala.concurrent.duration.Duration
trait FixtureHelper {
val data: Seq
val table: ???
def insertFixtures(db: Database) = {
Await.result(db.run(table.schema.create), Duration.Inf)
Await.result(db.run(table ++= data), Duration.Inf).get
}
}
我希望像以下一样使用它:
object EventFixtures extends FixtureHelper {
val data = Seq(...)
val table = TableQuery[EventsTable]
}
// in test code:
EventFixtures.insertFixtures()
问题是table
的类型。
table
的类型为slick.lifted.TableQuery[_ <: AbstractTable]
,只有在我使用此类型时才会找到行++=
,但无论如何都不会发生seq的隐式转换。< / LI>
table.schema
的类型为slick.profile.RelationalProfile#TableQueryExtensionMethods
,如果我在第1点声明table
,则找不到此属性。table.schema.create
的类型为slick.driver.JdbcActionComponent$SchemaActionExtensionMethodsImpl
,如果我在第2点声明table
,则找不到此属性。在原始代码中,table被实例化为TableQuery
,slick使用一些隐式转换来添加其他属性。它还必须将data
seq转换为E#TableElementType
的Iterable。
那么我怎么能一般地输入table
以便这个特性可以编译并且可以找到所有这些隐式添加的成员呢?
我认为这很简单,但似乎除非我用一个具体的类来实例化TableQuery
,否则整个事情就会崩溃。实际上,在我的不同fixture文件中,我用一个具体的表来实例化TableQuery,所以我需要的是让编译器知道它可用的属性和方法。
答案 0 :(得分:0)
如果您的表类外观定义为:
,您可以传递tableTag并将其用于创建TableQuery。case class Events(....)
class EventsTable(tag: Tag)
extends Table[Sample](tag, "sample_table") {
.....
}
这是您可以实施的方式:
import slick.driver.H2Driver.api._
import scala.slick.driver.H2Driver.simple.Tag
import scala.concurrent.Await
import scala.concurrent.duration.Duration
trait FixtureHelper {
val data: Seq
def insertFixtures[T,A <: Table[T]](tag : Tag => A ,db: Database) = {
val table : TableQuery[A] = TableQuery(tag) // create the tableQuery from the tag
Await.result(db.run(table.schema.create), Duration.Inf)
Await.result(db.run(table ++= data.toIterable), Duration.Inf).get // ++= accepts only Iterable[] values
}
}
你可以像
一样使用它object EventFixtures extends FixtureHelper {
val data = Seq(...)
}
// in test code:
val tag= new EventsTable(_)
EventFixtures.insertFixtures[Events,EventsTable](tag)