光滑插入,类型不匹配

时间:2017-03-06 18:50:26

标签: scala types slick

我正在尝试使用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\"}"))
    )

}

1 个答案:

答案 0 :(得分:2)

为了让这个答案缩短一点,我将引用DBIO[T],这是Slick中的别名DBIOAction[T, NoStream, Effect.All]

为什么会看到编译错误

该错误表示编译器需要DBIO[CustomerEvent]但找到DBIO[Unit]。它期望该类型,因为create被定义为返回Future[CustomerEvent](因此db.run应该返回)。

但是,Schema.CustomerEvents.userAction会调用DBIO.seqseq是一种组合操作并忽略结果的方法。 DBIO.seq的返回类型为DBIO[Unit](参考:Scala Doc)。

这就是你看错的原因:代码是使用抛弃结果的方法组合动作。

该怎么做

你可以做些一些事情。

  1. 如果您真的不想要插入的结果,请将create的类型更改为Future[Unit]

  2. 如果您确实需要非Unit结果,则需要切换到其他&#34;组合器&#34;比seq。在这种情况下,我建议andThen,它结合了两个动作,保留了第二个动作的值。我马上解释一下......

  3. 插入的结果

    +=默认返回受影响的行数。如果这是您想要的,那么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中描述了它。