23

我希望我的 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 testorplay run时,所有数据库访问都失败并显示:

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

我对此有几个问题:

  • 一般来说,我对在 Play 中如何配置数据库有点困惑:看起来像是 plain dbdb.[DBNAME]并且db. [DBNAME].url不同的教程在其中做出不同的选择。某些看起来应该可以工作的表达式(例如db.default.url = "jdbc:...",在预期对象的位置提供了字符串而失败)。

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

  • %env语法应该在 Play 2 中工作吗?

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

4

5 回答 5

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 Docs 中的更多详细信息:
http ://www.playframework.org/documentation/2.0/Configuration

于 2012-05-01T02:31:46.000 回答
13

至少在 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}

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

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

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 )

于 2013-04-27T14:11:18.527 回答
2

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

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.值放在一个单独的文件中,然后将其包含在我认为的主配置文件的末尾。

于 2013-01-09T01:22:24.513 回答
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了解我的示例实现。

希望这可以帮助。

于 2015-05-19T16:28:24.300 回答
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

于 2016-08-02T00:54:57.940 回答