8

是否可以通过配置为 postgresql 测试容器提供自定义 postgresql.conf 文件?

我已经包含了 Maven 依赖项

<dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>postgresql</artifactId>
            <version>1.10.6</version>
</dependency>

并为 DB url 使用“通过 JDBC URL 方案启动的数据库容器”因此我的 Spring Boot 应用程序中的设置如下:

datasource:
    url: jdbc:tc:postgresql:10-alpine:///databasename
    driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver

我需要在 postgresql.conf 中有一个自定义设置。有没有办法将 postgresql.conf 推送到由 testcontainers 启动的 docker 容器?

编辑 1

谢谢@vilkg,我确实知道 TC_INITSCRIPT 脚本选项和 SET 函数:

  • 我想要一个自定义设置,例如 my.key
  • ALTER 系统不适用于您自己的设置,例如:ALTER SYSTEM SET my.key = 'jehe'; 获取错误 无法执行 SQL 命令。返回消息:`错误:无法识别的配置参数“my.key”
  • 我以前尝试过如下 SET 和 ALTER DATABASE
SET my.key = 'new  value 8';    -- sets for current session 
ALTER DATABASE test SET my.key = 'new  value 8';  -- sets for subsequent sessions
select current_setting('my.key');

问题是

  • 当 testcontainer 启动 postgres 容器时,我将它传递给一个初始化脚本以运行 url: jdbc:tc:postgresql:10-alpine:///databasename?TC_INITSCRIPT=init_pg.sql
    • 我可以将上面的 SQL 包括在内,它很高兴..
    • 我知道该 secret.key 的设置在此脚本中正常工作,因为它将在 select current_setting('my.key'); 行上失败。如果其他两个被注释掉
    • 我也知道针对 db name test 运行它是正确的,例如:'ALTER DATABASE test' 因为如果我使用不同的名称,它会失败 Testcontainers 自动将应用程序连接到名为 test 的 db 所以以上所有我相信数据库设置得很好一切都应该很好

但是 当我在应用程序代码中使用'current_setting('my.key')'时它失败了

4

2 回答 2

8

如果您想继续使用 JDBC URL 方案启动 Postgres 容器,测试容器可以为您执行 init 脚本。该脚本必须在类路径中,引用如下:

jdbc:tc:postgis:9.6://hostname/databasename?TC_INITSCRIPT=somepath/init.sql

ALTER SYSTEM SET 命令是在 postgres 9.4 中引入的,所以你可以在你的 init 脚本中使用它。

另一种选择是使用数据库容器对象启动 postgres 容器并使用 withCopyFileToContainer() 方法。例子:

JdbcDatabaseContainer<?> postgisContainer = new PostgisContainerProvider()
        .newInstance()
        .withDatabaseName( POSTGRES_DATABASE_NAME )
        .withUsername( POSTGRES_CREDENTIALS )
        .withPassword( POSTGRES_CREDENTIALS )
        .withCopyFileToContainer(MountableFile.forClasspathResource("postgresql.conf"), "/var/lib/postgresql/data"));

编辑:

如果以上都不起作用,您可以重新配置 Postgres 命令并传递您的自定义配置键。您所需要的只是扩展PostgreSQLContainer并覆盖 configure() 方法。

@Override
protected void configure()
{
     setCommand( "postgres -c $your_config_key=$your_config_value"   );
}
于 2019-03-11T13:49:56.217 回答
1

我们必须创建我们的数据库和连接的用户。这是通过使用 Docker 映像中的环境变量来完成的。要更改 postgres.conf,我们可以使用 DockerFIle,我们将用新配置替换现有的 postgres.conf。

@ClassRule
public static GenericContainer postgresql= new GenericContainer(
  new ImageFromDockerfile("postgresql:10-alpine")
   .withDockerfileFromBuilder(dockerfileBuilder -> {
      dockerfileBuilder.from("myPostgresql:10-alpine")
      // root password is mandatory
      .env("PG_ROOT_PASSWORD", "root_password")
      .env("PG_DATABASE", "postgres")
      .env("PG_USER", "postgres")
      .env("PG_PASSWORD", "postgres")
})

接下来,我们必须创建一个数据库模式并填充数据库。从镜像文档中,目录 /docker-entrypoint-initdb.d 在启动时被扫描,所有带有 .sh、.sql 和 .sql.gz 扩展名的文件都会被执行。所以,我们只需要将文件 schema.sql 和 data.sql 放在这个目录中。一些参数可以通过 sql 请求运行数据库来设置

.withFileFromClasspath("a_schema.sql", "db/pg/schema.sql")
.withFileFromClasspath("b_data.sql", "db/pg/data.sql"))
于 2019-03-18T13:01:59.823 回答