我正在尝试使用Slick将一些数据插入到我的数据库中。我已成功查询数据库,但无法理解如何使用文档示例插入数据。
我已经达到了所谓的错误,即我的action
类型不正确而且会抛出错误
type mismatch;
found : slick.dbio.DBIOAction[Unit,slick.dbio.NoStream,slick.dbio.Effect.Write with slick.dbio.Effect.Schema]
required: slick.dbio.DBIOAction[com.ojolabs.customer.avro.CustomerEvent,slick.dbio.NoStream,Nothing]
db.run(action)
我不太确定如何使用我已编写的代码返回根据需要指定的类型。
我从这里调用我的架构:
trait CustomerEventsComponent {
def customEventsManager: CustomerEvents.Async
}
trait DefaultCustomerEvents extends CustomerEventsComponent{
self: DatabaseComponent with ExecutionContextComponent =>
lazy val customEventsManager = new Async {
override def create(phoneNumber: String, createdAt: DateTime): Future[CustomerEvent] = {
val action = Schema.CustomerEvents.userAction
//this is the line that throws the error
db.run(action)
}
}
}
我正在这里创建行动
object Schema {
class CustomerEvents(tag: Tag) extends Table[CustomerEvent](tag, "customer_events") {
def id: Rep[UUID] = column[UUID]("id", O.PrimaryKey)
def customerId: Rep[UUID] = column[UUID]("customer_id")
def eventType: Rep[String] = column[String]("type")
def createdAt: Rep[DateTime] = column[DateTime]("created_at")
def version: Rep[Double] = column[Double]("version")
def data: Rep[JsValue] = column[JsValue]("data")
def metadata: Rep[JsValue] = column[JsValue]("metadata")
def * = (id, customerId, eventType, createdAt, version, data, metadata) <> (CustomerEvent.tupled, CustomerEvent.unapply)
}
object CustomerEvents {
val all = TableQuery[CustomerEvents]
val userAction = DBIO.seq(
all.schema.create,
all += CustomerEvent(
UUID.randomUUID(),
UUID.randomUUID(),
"hello",
DateTime.now(),
1.0,
Json.toJson("{\"hello\" : \"its me\"}"),
Json.toJson("{\"hello\" : \"its me\"}"))
)
}
答案 0 :(得分:2)
为了让这个答案缩短一点,我将引用DBIO[T]
,这是Slick中的别名DBIOAction[T, NoStream, Effect.All]
该错误表示编译器需要DBIO[CustomerEvent]
但找到DBIO[Unit]
。它期望该类型,因为create
被定义为返回Future[CustomerEvent]
(因此db.run
应该返回)。
但是,Schema.CustomerEvents.userAction
会调用DBIO.seq
。 seq
是一种组合操作并忽略结果的方法。 DBIO.seq
的返回类型为DBIO[Unit]
(参考:Scala Doc)。
这就是你看错的原因:代码是使用抛弃结果的方法组合动作。
你可以做些一些事情。
如果您真的不想要插入的结果,请将create
的类型更改为Future[Unit]
如果您确实需要非Unit
结果,则需要切换到其他&#34;组合器&#34;比seq
。在这种情况下,我建议andThen
,它结合了两个动作,保留了第二个动作的值。我马上解释一下......
+=
默认返回受影响的行数。如果这是您想要的,那么Future[Int]
上的create
类型就是userAction
类型。
all.schema.create andThen (all += ...etc)
最终会:for {
_ <- all.schema.create
rowsAffected <- all += ...etc
} yield rowsAffected
如果您愿意,也可以使用for comprehension:
andThen
(不是yield
使用,但结果相同)。
但是,如果您希望将案例类作为结果......那么,您创建案例类,因此您可以returning
将其作为上面的理解示例。 Slick还支持into
和+=
作为更改flushAppendOnlyFile
表达式的返回类型的方式:the reference manual中描述了它。