如何运行使用Play Framework应用程序数据库的命令行scala脚本?

时间:2014-05-10 15:59:32

标签: java scala playframework playframework-2.0

我在app/scripts文件夹上有这个(我在app/内创建了这个文件夹)。我不确定如何在这里正确设置类路径,因此我甚至没有运行它来知道它是否实际连接到数据库。如何从命令行以干净的方式运行它?

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 个答案:

答案 0 :(得分:4)

我发了一篇博文来解释我的最终解决方案。应该作为问题的答案。

http://blog.felipe.rs/2014/05/15/run-maintenance-scripts-in-the-context-of-a-running-play-framework-application/

答案 1 :(得分: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://stackoverflow.com/a/11297578/2556428

答案 2 :(得分:0)

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

在主playframework项目中创建空子项目。

在build.sbt中,它看起来像

&map

和sjutil / build.sbt就像普通的sbt项目一样需要额外的代表,对我来说这是akka-remote

pub fn fib_hash(n: u32) -> u64 {
    // This is the engine which recurses saving each value in the map
    fn f(map: HashMap<u32, u64>, n: u32) -> (HashMap<u32, u64>, u64) {
        if let Some(&number) = map.get(&n) {
            return (map, number);
        }
        let (map, a) = f(map, n - 1);
        let (mut map, b) = f(map, n - 2);
        let res = a + b;
        map.insert(n, res);
        (map, res)
    }
    let mut map = HashMap::new();
    map.insert(0, 0);
    map.insert(1, 1);
    map.insert(2, 1);
    f(map, n).1
}

您可以在sjutil /文件夹中直接放置一些App

sjutil / actorsstarter.scala:

// 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)

之后,您可以使用以下命令运行此脚本:

name := "sjutil"

version := "1.0-SNAPSHOT"

scalaVersion := "2.11.1"

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

并使用正常项目完成所有事情:stage,dist等。