【问题标题】:Slick insert from select从选择中插入光滑
【发布时间】:2015-01-12 13:10:49
【问题描述】:

我使用 scala 2.11 和 slick 2.1.0 并编译了代码:

   trait TSegmentClient { this: Profile =>

        import profile.simple._

        class SegmentClients(tag: Tag) extends Table[(Int, Long)](tag, "seg") {

            def segmentId = column[Int]("segment_id")
            def clientId = column[Long]("client_id")

            def * = (segmentId, clientId)
        }
    }

    segmentClients.insert(clientBehaviors.map(c => (1, c.clientId)))

它有效。

但我需要这样的案例类:

case class SegmentClient(segmentId: Int, clientId: Long)

trait TSegmentClient { this: Profile =>

    import profile.simple._

    class SegmentClients(tag: Tag) extends Table[SegmentClient](tag, "seg") {

        def segmentId = column[Int]("segment_id")
        def clientId = column[Long]("client_id")

        def * = (segmentId, clientId) <> (SegmentClient.tupled, SegmentClient.unapply)
    }
}

segmentClients.insert(clientBehaviors.map(c => (1, c.clientId)))

但它不能编译。

(值:models.coper.datamining.SegmentClient)(隐式会话: scala.slick.jdbc.JdbcBackend#SessionDef)Int 不能应用于 (scala.slick.lifted.Query[(scala.slick.lifted.Column[Int], scala.slick.lifted.Column[Long]),(Int, Long),Seq]) segmentClients.insert(clientBehaviors.map(c => (segmentId, c.clientId)))

我的代码有什么问题?

【问题讨论】:

  • def tuple = (segmentId, clientId); def * = 元组 (SegmentClient.tupled, SegmentClient.unapply);和 segmentClients.tuple.insert(...) ?
  • 对不起,我不明白。在我的示例 2 中,我需要将 def * = (segmentId, clientId) &lt;&gt; (SegmentClient.tupled, SegmentClient.unapply) 更改为 tuple = (segmentId, clientId); def * = tuple &lt;&gt; (SegmentClient.tupled, SegmentClient.unapply),然后再更改 segmentClients.tuple.insert(clientBehaviors.map(c =&gt; (1, c.clientId))) 吗?编译器说,该值元组不是 scala.slick.lifted.TableQuery 的成员
  • 我的错误,使用:segmentClients.map(_.tuple).insert(...)
  • 太好了!它有效,谢谢!请添加您的答案,以便我标记它

标签: scala slick


【解决方案1】:

您可以使用另一个投影到未映射到案例类的元组来执行此操作。

case class SegmentClient(segmentId: Int, clientId: Long)

trait TSegmentClient { this: Profile =>

    import profile.simple._

    class SegmentClients(tag: Tag) extends Table[SegmentClient](tag, "seg") {

        def segmentId = column[Int]("segment_id")
        def clientId = column[Long]("client_id")
        def tuple = (segmentId, clientId) 
        def * = tuple <> (SegmentClient.tupled, SegmentClient.unapply)
    }
}

segmentClients.map(_.tuple).insert(clientBehaviors.map(c => (1, c.clientId)))

【讨论】:

  • 嘿@cvogt。在 slick 3+ 中执行此操作的正确方法是什么?
  • 尝试 forceInsertQuery。见this doc的最后部分
【解决方案2】:

第二个示例中segmentClients 上的insert 方法需要SegmentClient 实例,因为SegmentClientsmapped table。这就是编译器错误消息的基本含义。我不知道是否有更惯用的方法,因为我不太了解 Slick,但作为一种解决方法,您也可以使用:

val behaviours = clientBehaviours.list.map(c => SegmentClient(1, c.clientId))
segmentClients.insertAll(behaviours)

【讨论】:

  • 你的代码没有编译,我可以这样做:for (c &lt;- clientBehaviours.list) yield segmentClients.insert(new SegmentClient(1, c.clientId)) 但速度很慢。我需要一个请求在服务器端执行
  • SegmentClient 需要 Int、Long,但 c.clientId 是 scala.slick.lifted.Column[Long]
  • 对于c.clientId 有一个Column 意味着您仍在查询中,但是list 应该返回一个List 的任何ClientBehaviour 表映射到的@。您还可以发布clientBehaviours 实际上是什么类型。也许我错过了什么,但好像你没有打电话给list。您是否已经尝试过 cvogt 的建议?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 2018-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多