首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Slick run方法返回的Future在插入行之前成功完成

Slick run方法返回的Future在插入行之前成功完成
EN

Stack Overflow用户
提问于 2019-03-26 23:38:10
回答 1查看 0关注 0票数 0

我正在使用Slick和PostgreSQL来存储Scala应用程序。我有一个方法foo从CSV文件中读取数据并将大约10,000行插入数据库。在行插入操作的Future完成之后,bar将调用另一个方法,该方法从数据库中检索这些行并对它们执行某些操作。这就是问题所在:实际上没有从数据库中检索到任何行,因为在Future完成时没有插入任何行。

从我在寻找答案时可以收集到的内容和官方文档中,在插入语句成功执行之前,Future不应该完成。如果我添加以下代码Thread.sleep(30000)bar,允许插入语句首先执行,该方法提供了预期的结果。现在,出于显而易见的原因,我宁愿不这样做,所以我正在寻找替代方案。

下图说明了doStuff调用初始方法后的程序流程:

程序流程图
程序流程图

doStufffoo在返回Future之前,加载数据并将其存储在数据库中的调用。doStuff然后在这个Future中进行映射并进行调用barbarbar从数据库中检索行并处理它们。但是,由于在bar调用的位置没有插入任何行,因此不会处理任何数据。

doStuff方法:

代码语言:javascript
复制
def doStuff(csvFile: File): Future[Unit] = {
  fooService.foo(csvFile)
    .map(_ => {
      csvFile.delete()
      barService.bar()
    })
}

foo方法:

代码语言:javascript
复制
def foo(file: File) Future[Unit] = {
  val reader = CSVReader.open(file)
  fooStorage.truncateFooData().map(_ => {
    val foos = for (line <- reader.iterator if
    line.head != "bad1" &&
      line.head !="bad2")
      yield parseFooData(line)
    fooStorage.saveFooDataBulk(foos.toSeq)
  })
}

我如何使用Slick插入行:

代码语言:javascript
复制
override def saveFooDataBulk(fooSeq: Seq[Foo]): Future[Seq[Foo]] =
  db.run(DBIO.seq(fooQuery ++= fooSeq)).map(_ => fooSeq)

我希望bar一旦所有行都插入到数据库中就会被调用,而不是更早,但是,目前来自Slick的Future很快就完成了。如果它是相关的:doStuff当请求被发送到Akka Http端点时调用该方法。应用程序和数据库在两个不同的docker容器中运行。我究竟做错了什么?

另外,我无法理解我一年半前选择的用户名是多么合适。

EN

回答 1

Stack Overflow用户

发布于 2019-03-27 09:34:48

更换mapflatMapdef foo。否则,它会启动一个Future[Seq[Foo]],然后立即返回一个(),然后由你丢弃doStuff。如下:

代码语言:javascript
复制
fooStorage
  .truncateFooData()
  .flatMap(_ => {
    /* stuff... */
    fooStorage.saveFooDataBulk(foo.toSeq)
  })
  .map(_ => ())

我没有测试它,但无论如何,Future在另一个中间开始一些s Future.map然后立即返回一个()感觉不太好。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100008992

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档