我想创建一个使用slick创建数据库模式的set任务。为此,我的项目中有一个如下的任务对象:
object CreateSchema {
val instance = Database.forConfig("localDb")
def main(args: Array[String]) {
val createFuture = instance.run(createActions)
...
Await.ready(createFuture, Duration.Inf)
}
}
在我的build.sbt
我定义了一个任务:
lazy val createSchema = taskKey[Unit]("CREATE database schema")
fullRunTask(createSchema, Runtime, "sbt.CreateSchema")
当我从命令行运行sbt createSchema
时,它会按预期执行。
然而,问题是似乎没有考虑application.conf
(我也尝试过不同的范围,例如Compile
或Test
)。因此,任务因com.typesafe.config.ConfigException$Missing: No configuration setting found for key 'localDb'
而失败。
如何解决此问题,以便配置可用?
我发现很多问题都涉及在application.conf
内部使用build.sbt
,但这不是我需要的。
答案 0 :(得分:3)
我已经使用SBT 0.13.8和Slick 3.0.0设置了一个小程序,它正在按预期工作。 (甚至不修改“-Dconfig.resource”。)
name := "SO_20150915"
version := "1.0"
scalaVersion := "2.11.7"
libraryDependencies ++= Seq(
"com.typesafe" % "config" % "1.3.0" withSources() withJavadoc(),
"com.typesafe.slick" %% "slick" % "3.0.0",
"org.slf4j" % "slf4j-nop" % "1.6.4",
"com.h2database" % "h2" % "1.3.175"
)
lazy val createSchema = taskKey[Unit]("CREATE database schema")
fullRunTask(createSchema, Runtime, "somefun.CallMe")
sbt.version = 0.13.8
hello {
world = "buuh."
}
h2mem1 = {
url = "jdbc:h2:mem:test1"
driver = org.h2.Driver
connectionPool = disabled
keepAliveConnection = true
}
package somefun
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import slick.driver.H2Driver.api._
/**
* SO_20150915
* Created by martin on 15.09.15.
*/
object CallMe {
def main(args: Array[String]) : Unit = {
println("Hello")
val settings = new Settings()
println(s"Settings read from hello.world: ${settings.hw}" )
val db = Database.forConfig("h2mem1")
try {
// ...
println("Do something with your database.")
} finally db.close
}
}
class Settings(val config: Config) {
// This verifies that the Config is sane and has our
// reference config. Importantly, we specify the "di3"
// path so we only validate settings that belong to this
// library. Otherwise, we might throw mistaken errors about
// settings we know nothing about.
config.checkValid(ConfigFactory.defaultReference(), "hello")
// This uses the standard default Config, if none is provided,
// which simplifies apps willing to use the defaults
def this() {
this(ConfigFactory.load())
}
val hw = config.getString("hello.world")
}
如果从控制台运行sbt createSchema
,我获取输出
[info] Loading project definition from /home/.../SO_20150915/project
[info] Set current project to SO_20150915 (in build file:/home/.../SO_20150915/)
[info] Running somefun.CallMe
Hello
Settings read from hello.world: buuh.
Do something with your database.
[success] Total time: 1 s, completed 15.09.2015 10:42:20
答案 1 :(得分:1)
因此,即使您的代码位于src
- 文件夹中,也会从SBT中调用它。这意味着,您尝试从SBT的类路径上下文中的加载application.conf
。
光滑在内部使用Typesafe Config
。 (因此下面的方法(在后面描述)不适用,因为您无法修改Config加载机制本身。)
请尝试通过application.conf
,see typesafe config docu (search for config.resource)
config.resource
的路径
在开始config.resource
之前设置sbt
(通过-Dconfig.resource = ...)
或者在build.sbt中作为Scala代码
sys.props("config.resource") = "./src/main/resources/application.conf"
或通过
在SBT中创建Task
lazy val configPath = TaskKey[Unit]("configPath", "Set path for application.conf")
并添加
configPath := Def.task {
sys.props("config.resource") = "./src/main/resources/application.conf"
}
到您的设置序列。
如果有效,请告诉我。
最近,我正在为SBT编写一个自定义插件,我也尝试访问reference.conf
。很抱歉,我无法使用默认.conf
访问放置在project
- 子文件夹中的任何ClassLoader
。
最后我在testenvironment.conf
文件夹中创建了一个project
并使用以下代码加载(类型安全)配置:
def getConfig: Config = {
val classLoader = new java.net.URLClassLoader( Array( new File("./project/").toURI.toURL ) )
ConfigFactory.load(classLoader, "testenvironment")
}
或从application.conf
加载基因./src/main/resources
:
def getConfig: Config = {
val classLoader = new java.net.URLClassLoader( Array( new File("./src/main/resources/").toURI.toURL ) )
// no .conf basename given, so look for reference.conf and application.conf
// use specific classLoader
ConfigFactory.load(classLoader)
}