如何运行一个使用Play框架应用程序数据库的命令行Scala脚本?

4

我在app/文件夹里创建了一个app/scripts文件夹,里面有这个内容。我不确定如何正确地设置类路径,因此甚至没有运行它来知道它是否可以连接到数据库。我该如何从命令行中以清晰的方式运行它?

package scripts

import scala.collection.TraversableOnce
import scala.collection.generic.SeqForwarder
import scala.io.Source
import scala.slick.jdbc.{StaticQuery => Q}
import scala.slick.session.Session
import scala.slick.session.Database
import play.api.db.DB
import tables.Campeonatos
import tables.Jogos
import org.postgresql.Driver
import play.api.test._
import play.api.test.Helpers._

// ...

class InsertJogosCSV extends App {
  val dao = new DAO()
  val application = FakeApplication()

  def insertJogos(csv: CSV)(implicit s: Session) = {
    val times = dao.getTimeIdByNameMap
    var count = 0
    csv foreach { case cols =>
      count += 1
      dao.insertJogo(cols, times)
    }
    count
  }

  val csvFilePath: String = args(0)
  val csv = new CSV(csvFilePath)
  csv.printLines
  running(application) {
    val realDatabase = Database.forDataSource(DB.getDataSource()(application))
    implicit val s = realDatabase.createSession
    insertJogos(csv)
  }
}
3个回答

3

@Alex http://blog.felipe.rs/2014/05/15/run-maintenance-scripts-in-the-context-of-a-running-play-framework-application/ - felipecrv
@philinx 两个都可以。你是移动了条目还是服务器卡住了?不管怎样,问题已经解决了。感谢你的修复。 - Alexander Oh
@Alex,日期中的天数有误差。我认为这是由于生活在不同时区导致的某些错误。 :) - felipecrv

1
您可以通过在应用程序的根目录使用play test:console命令来实现此目的。首先,您可能需要将代码移动到一个主方法中,而不是扩展App
class InsertJogosCSV {
    def main(args: Array[String]) {
        val dao = new DAO()
        val application = FakeApplication()

        def insertJogos(csv: CSV)(implicit s: Session) = {....}

        ....
    }
}

然后运行play test:console命令并执行以下操作

scala> import scripts.InsertJogosCSV
import scripts.InsertJogosCSV

scala> val insert = new InsertJogosCSV()
insert: scripts.InsertJogosCSV = scripts.InsertJogosCSV@7d5f9d2b

scala> insert.main
res0: .....

默认情况下,play test:console 将 app 文件夹中的所有内容添加到您的类路径中,以及您脚本所需的 FakeApplication 上下文。希望这有所帮助。
类似问题: https://dev59.com/FmXWa4cB1Zd3GeqPMWNl#11297578

那肯定有所帮助。我开始学习如何创建SBT任务来执行此操作。SBT非常复杂,我仍在阅读文档以找到处理任务中文件路径参数的最简单方法。目前我将使用test:console。谢谢! - felipecrv

0

我正在使用另一种方法来完成类似的任务。

在主Play框架项目中创建一个空的子项目。

在build.sbt文件中,它看起来像:

// Main project
lazy val root = (project in file(".")).enablePlugins(play.PlayScala).enablePlugins(com.typesafe.sbt.web.SbtWeb)
// Utils sbt project with scripts
lazy val sjutil = project.aggregate(root).dependsOn(root)

sjutil/build.sbt 是一个普通的 sbt 项目,如有必要,可以添加额外的依赖项,对我而言,它是 akka-remote。

name := "sjutil"

version := "1.0-SNAPSHOT"

scalaVersion := "2.11.1"

libraryDependencies +=   "com.typesafe.akka" %% "akka-remote" % "2.3.4"

你可以直接将一些应用放在sjutil/文件夹中

sjutil/actorsstarter.scala:

object actorsstarter {
  lazy val logger = play.api.Logger("actorsstarter")
  def main(args: Array[String]) {
     // read config from conf/application.conf of main project
     val remoteConfig = ConfigFactory.load.getConfig("botstarter")

     val system = ActorSystem("application",remoteConfig)
     val path = "akka.tcp://application@127.0.0.1:2553/user"
     ....
     logger.info("Started")
  }
}

之后你可以使用以下命令运行这个脚本:

./activator sjutil/run 

并且可以完成普通项目中的所有操作:stage、dist等。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接