【问题标题】:Insert records in batch Slick批量插入记录 Slick
【发布时间】:2017-11-26 18:25:31
【问题描述】:

我想在Task表中插入10多行数据,所以我创建了这些记录的列表。除了我的表之外,我还有一个具有创建、更新等功能的存储库。所以我可以使用创建函数来添加一条记录,但我想使用这个函数批量插入数据。

case class Task (
  idTask: Option[Long],
  ownerId: Long,
  name: String,
  finished: Boolean
)

class TaskTable(tag: Tag) extends Table[Task](tag, "tasks"){
  val idTask = column[Long]("id_task", O.PrimaryKey)
  val ownerId = column[Long]("owner")
  val name = column[String]("name")
  val finished = column[Boolean]("finished")

  val ownerFk = foreignKey("owner_id_fk", ownerId, TableQuery[UserTable])(_.idUser)

  def * = (idTask.?, ownerId, name, finished) <> (Task.apply _ tupled, Task.unapply)
}

object TaskTable{
  lazy val table = TableQuery[TaskTable]
}

class TaskRepository(db: Database) {
  val taskTableQuery = TableQuery[TaskTable]
  def create(task: Task): Future[Task] =
    db.run(taskTableQuery returning taskTableQuery += task)

 def createTasks(tasks: List[Task]): Future[Option[Task]] = 
    db.run(taskTableQuery ++= tasks)

  def update(task: Task): Future[Int] =
    db.run(taskTableQuery.filter(_.idTask === task.idTask).update(task))

  def delete(task: Task): Future[Int] =
    db.run(taskTableQuery.filter(_.idTask === task.idTask).delete)

  def getById(task: Task): Future[Option[Task]] =
    db.run(taskTableQuery.filter(_.idTask === task.idTask).result.headOption)
}

我尝试过这样做:

val tasks = List(
    Task(Some(1),  1,"Analyze logs with Spark", false),
    Task(Some(2),  1,"Clean and process data", false),
...
)
val createTasks = tasks.map(taskRepository.create(_))

但是这个 createTasks 值的类型是 Unit,我不能用 db.runAwait.result 运行它。由于返回类型不匹配,我的方法 createTasks 无法编译。 那么如何为批量插入创建此方法或更改现有方法? 如果有任何帮助,我将不胜感激!

【问题讨论】:

  • 由于您描述的是计算,而不是执行它们,您需要使用map 而不是foreach
  • @SeanVieira 你的意思是users.map(userRepository.create(_)) ?但它仍将用户列表返回为Future[List[User]],我无法将其传递给db.runAwait.result 函数

标签: postgresql scala batch-processing slick


【解决方案1】:

如果您在编译时知道动作,请使用DBIO.seq() 链接数据库动作:

db.run(
  DBIO.seq( taskTableQuery += Task(....), 
            taskTableQuery += Task(....), 
            taskTableQuery += Task(....)...
  ).transactionally
)

否则,使用DBIO.sequence:

val taskSeq:Seq[Task] = ... however you get the tasks
db.run( 
    DBIO.sequence( taskSeq.map(t=>taskTableQuery+=t) ).transactionally 
)

【讨论】:

  • 这不是我想要的我宁愿传递任务列表。不过还是谢谢
  • 谢谢。太棒了!
猜你喜欢
  • 1970-01-01
  • 2017-12-29
  • 1970-01-01
  • 1970-01-01
  • 2020-03-18
  • 2011-02-20
  • 1970-01-01
  • 2016-05-02
  • 2019-06-19
相关资源
最近更新 更多