如何在Play 2.0中为每个环境设置不同的数据库?

时间:2012-04-30 23:52:34

标签: database scala configuration playframework playframework-2.0

我希望我的Play应用程序使用不同的数据库进行测试,本地和生产(生产是Heroku)环境。

application.conf我有:

db.default.driver=org.postgresql.Driver 

%dev.db.default.url="jdbc:postgresql://localhost/foobar" 
%test.db.default.url="jdbc:postgresql://localhost/foobar-test" 
%prod.db.default.url=${DATABASE_URL} 

这似乎不起作用。当我运行play testplay run时, 所有数据库访问都失败了:

 Configuration error [Missing configuration [db.default.url]] (Configuration.scala:258) 

我对此有几个问题:

  • 一般来说,我对数据库的配置方式有点困惑 在Play中:它看起来像普通dbdb.[DBNAME]db. [DBNAME].url,不同的教程做出了不同的选择 那些。某些似乎应该起作用的表达式(例如db.default.url = "jdbc:..."失败,并且在预期对象的位置提供了字符串错误。)

  • 我见过其他人建议我创建单独的prod.confdev.conftest.conf文件,每个文件都包含application.conf,然后包含特定于数据库的配置。但在这种情况下,如何从Play控制台运行test时指定要使用的数据库?

  • %env语法是否适用于Play 2?

  • 指定play test使用的环境的正确方法是什么?

5 个答案:

答案 0 :(得分:21)

在Play 2中,没有不同的配置环境。相反,您只需设置或覆盖conf/application.conf文件中的配置参数。一种方法是在play命令行上,例如:

play -Ddb.default.driver=org.postgresql.Driver -Ddb.default.url=$DATABASE_URL ~run

您还可以告诉Play使用其他配置文件:

play -Dconfig.file=conf/prod.conf ~run

有关Heroku的示例Procfile,请参阅:
https://github.com/jamesward/play2bars/blob/scala-anorm/Procfile

Play文档中的更多详细信息:
http://www.playframework.org/documentation/2.0/Configuration

答案 1 :(得分:11)

至少在Play 2.1.1中,如果设置了环境变量,可能会覆盖配置值。 (详见:http://www.playframework.com/documentation/2.1.1/ProductionConfiguration

因此,您可以在conf/application.conf中设置以下内容:

db.default.url="jdbc:mysql://localhost:3306/my-db-name"
db.default.url=${?DATABASE_URL_DB}

默认情况下,它将使用定义的JDBC-URL,除非环境变量DATABASE_URL_DB为其定义了值。 因此,您只需在配置中设置开发数据库,​​并为生产或阶段设置环境变量。

但要注意,如果将变量引用放在带引号的字符串中,则此替换不起作用:

db.default.url="jdbc:${?DATABASE_URL_DB}"

相反,只是取消引用要替换的部分,例如。

database_host = "localhost"
database_host = ${?ENV_DATABASE_HOST}
db.default.url="jdbc:mysql://"${?database_host}":3306/my-db-name"

在此示例中,如果未设置环境变量ENV_DATABASE_HOST,则默认情况下将使用localhost。 (详见:https://www.playframework.com/documentation/2.5.x/ConfigFile#substitutions

答案 2 :(得分:2)

如果您在加载配置值时检查Play.isTest,然后在加载的属性前加上'test',则实际上您仍然可以在Play 2中使用Play 1.0配置值命名方法。这是一个剪辑:

def configPrefix = if (play.api.Play.isTest) "test." else ""

def configStr(path: String) =
  Play.configuration.getString(configPrefix + path) getOrElse
     die(s"Config value missing: $configPrefix$path")

new RelDb(
  server = configStr("pgsql.server"),
  port = configStr("pgsql.port"),
  database = configStr("pgsql.database"),
  user = ...,
  password = ...)

相关的配置代码段:

pgsql.server="192.168.0.123"
pgsql.port="5432"
pgsql.database="prod"
...

test.pgsql.server="192.168.0.123"
test.pgsql.port="5432"
test.pgsql.database="test"
...

现在,您无需记住在运行e2e测试套件时设置任何系统属性,并且您不会意外连接到prod数据库。

我想您可以选择将test.值放在一个单独的文件中,然后将其包含在我认为的主配置文件的末尾。

答案 3 :(得分:0)

还有另一种方法是覆盖Global / GlobalSettings方法 onLoadConfig ,然后您可以使用通用配置和特定环境配置设置应用程序配置,如下所示......

conf/application.conf --> configurations common for all environment
conf/dev/application.conf --> configurations for development environment
conf/test/application.conf --> configurations for testing environment

conf/prod/application.conf --> configurations for production environment

您可以查看http://bit.ly/1AiZvX5我的示例实施。

希望这有帮助。

答案 4 :(得分:0)

偏离主题,但是如果你遵循12-factor-app,那么以环境命名的单独配置是不好的:

Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called “environments”) named after specific deploys, such as the development, test, and production environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as staging or qa. As the project grows further, developers may add their own special environments like joes-staging, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle

来源:http://12factor.net/config