【问题标题】:Use Mysql in dev/prod and H2 in test在 dev/prod 中使用 Mysql,在测试中使用 H2
【发布时间】:2013-04-10 17:05:45
【问题描述】:
使用 play framework 2.1,我试图找到拥有两种不同数据库配置的最佳方式:
- 一个基于 mysql 运行我的应用程序
- 基于 H2 测试我的应用程序
虽然做其中一个很容易,但当我尝试同时做这两个时遇到以下问题:
- 我无法拥有相同的数据库演变,因为即使在 mysql 模式下,某些 mysql 特定命令也无法与 H2 一起使用:这意味着两组演变和两个单独的数据库名称
- 我不确定如何将主 application.conf 文件覆盖为另一个保留以在测试模式下进行测试的文件。我尝试过的(从命令行传递文件名或覆盖键)似乎保留给 prod 模式。
我的问题:任何人都可以推荐一个好方法(始终使用 mysql,并且仅在测试中使用 H2),而不会过度复杂地运行应用程序吗? Google 没有帮助我。
感谢您的帮助。
【问题讨论】:
标签:
mysql
playframework-2.0
【解决方案1】:
您可能会发现一些有用的技巧。
首先,MySQL 的/*! */ 表示法允许您添加 MySQL 将遵循但其他 DB 将忽略的代码,例如:
create table Users (
id bigint not null auto_increment,
name varchar(40)
) /*! engine=InnoDB */
这不是灵丹妙药,但它可以让您了解 MySQL 和 H2 语法之间的一些差异。这是一个 MySQL 主义,所以它对其他数据库没有帮助,但由于大多数其他数据库不像 MySQL 那样古怪,你可能不需要它——我们将我们的数据库从 MySQL 迁移到 PostgreSQL,它没有支持 /*! */ 表示法,但 PostgreSQL 与 H2 足够相似,我们不需要它。
如果您想为 dev 和 prod 使用不同的配置,您最好为 prod 提供额外的配置。这样做的原因是您可能会使用play run 启动您的开发服务器,并使用play stage; target/start 启动您的产品服务器。 target/start 可以采用 -Dconfig.resource 参数。例如,为 prod 创建一个额外的配置文件 prod.conf,如下所示:
include "application.conf"
# Extra config for prod - this will override the dev values in application.conf
db.default.driver=...
db.default.url=...
...
并创建一个start_prod 脚本,如下所示:
#!/bin/sh
# Optional - you might want to do this as part of the build/deploy process instead
#play stage
target/start -Dconfig.resource=prod.conf
理论上,你可以反过来做,让application.conf 包含 prod conf,并创建一个 dev.conf 文件,但你可能需要一个脚本来启动 prod(你可能会最终需要额外的 JVM/内存/GC 参数,或者将其添加到 rc.d 中,或其他)。
【解决方案2】:
使用不同的数据库引擎可能是最糟糕的情况,正如您自己写的那样:某些功能、保留关键字等方面的差异导致您有时需要为选定的数据库引擎编写自定义语句非常。最好使用使用同一引擎的两个独立数据库。
不幸的是,我不知道配置覆盖的问题,所以如果覆盖配置的默认方法失败......覆盖 application.conf 中的 id - 这样你就可以快速评论整个块......)
【解决方案3】:
以下是如何使用内存数据库进行测试:
public class ApplicationTest extends WithApplication {
@Before
public void setup() {
start(fakeApplication(inMemoryDatabase("default-test"), fakeGlobal()));
}
/// skipped ....
}
inMemoryDatabase() 默认使用 H2 驱动。
您可以在source code找到更多详细信息