【问题标题】:MySQL TestContainers init-script Schema Creation FailingMySQL TestContainers init-script 模式创建失败
【发布时间】:2021-03-09 21:38:04
【问题描述】:

尝试在 MySQL 测试容器实例中创建架构时遇到以下问题。测试用户好像没有相应的权限?

配置:

spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver
spring.datasource.url=jdbc:tc:mysql:5.7.22:///test?TC_INITSCRIPT=component/db/init_mysql.sql
Caused by: org.testcontainers.ext.ScriptUtils$UncategorizedScriptException: Failed to execute database script from resource [create schema new_schema CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;]
    at org.testcontainers.ext.ScriptUtils.executeDatabaseScript(ScriptUtils.java:375)
    at org.testcontainers.ext.ScriptUtils.executeDatabaseScript(ScriptUtils.java:313)
    at org.testcontainers.jdbc.ContainerDatabaseDriver.runInitScriptIfRequired(ContainerDatabaseDriver.java:196)
    at org.testcontainers.jdbc.ContainerDatabaseDriver.connect(ContainerDatabaseDriver.java:132)
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:136)
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:369)
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:198)
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:467)
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:541)
    ... 61 more
Caused by: org.testcontainers.ext.ScriptUtils$ScriptStatementFailedException: Script execution failed (component/db/init_mysql.sql:1): create schema new_schema CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
    at org.testcontainers.jdbc.JdbcDatabaseDelegate.execute(JdbcDatabaseDelegate.java:49)
    at org.testcontainers.delegate.AbstractDatabaseDelegate.execute(AbstractDatabaseDelegate.java:34)
    at org.testcontainers.ext.ScriptUtils.executeDatabaseScript(ScriptUtils.java:362)
    ... 69 more
Caused by: java.sql.SQLSyntaxErrorException: Access denied for user 'test'@'%' to database 'new_schema'
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
    at com.mysql.cj.jdbc.StatementImpl.executeInternal(StatementImpl.java:782)
    at com.mysql.cj.jdbc.StatementImpl.execute(StatementImpl.java:666)
    at org.testcontainers.jdbc.JdbcDatabaseDelegate.execute(JdbcDatabaseDelegate.java:42)
    ... 71 more

组件/db/init_mysql.sql

create schema new_schema CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

在 JDBC 集成之外创建 mysql 映像时遇到类似问题:

private static final MySQLContainer mysqlContainer = new MySQLContainer<>(DockerImageName.parse("mysql:5.7"))
            .withInitScript("component/db/init_mysql.sql")
            .withUsername("user")
            .withPassword("password")
            .withExposedPorts(3306)
            .withReuse(true);

关于如何在不使用预先创建的架构创建自定义 docker 映像的情况下实现这一点的任何想法?

任何帮助将不胜感激我觉得我一定在这里遗漏了一些东西。

【问题讨论】:

标签: java mysql spring-boot testcontainers


【解决方案1】:

尝试创建 MySQL 容器并为root 使用与test 用户相同的密码,在本例中为whatever

@Container
private static MySQLContainer database = new MySQLContainer(MYSQL_DOCKER_TEST_VERSION)
            .withUsername("test")
            .withPassword("whatever")
...

通过@DynamicPropertySource 动态添加属性。

    @DynamicPropertySource
    static void databaseProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", database::getJdbcUrl);
        registry.add("spring.datasource.username", database::getUsername);
        registry.add("spring.datasource.password", database::getPassword);
        registry.add("flyway.user", () -> "root");
        registry.add("flyway.password", database::getPassword);
    }

我没有使用 flyway,但我相信它应该可以工作。

【讨论】:

    【解决方案2】:

    正如在 testcontainers 存储库上创建的测试中所见,解决方法是指定 root 用户的密码并在测试中使用 root 用户:

    MySQLContainer<?> db = new MySQLContainer<>(image)
                .withUsername("test")
                .withPassword("test")
                .withEnv("MYSQL_ROOT_PASSWORD", "test")
                ...
    

    参考:https://github.com/testcontainers/testcontainers-java/commit/2fa00ddbd1f42a20656d5e39d58cdedfbd483dcf#diff-f49cf0d09246a5351504ca32a08deb74e80ac7d61ad012f02d8f09c36508737bR65

    【讨论】:

      【解决方案3】:

      通过使用预先创建的模式创建自定义 MySQL 映像来解决此问题。很想知道是否有更好的方法。

      【讨论】:

      • 这不是一个坏方法,因为预创建的图像使容器启动时间更短。
      • 您是如何实施此解决方案的?我有同样的问题,不胜感激。
      【解决方案4】:

      我遇到了同样的问题,我使用以下方法解决了它:

          @Container
           public static JdbcDatabaseContainer mariaDB = (JdbcDatabaseContainer) new MariaDBContainer("mariadb:10.5.11-focal")
          .withDatabaseName("dbName")
          .withInitScript("db.migration/init.sql")
          .withUsername("your user")
          .withPassword("your password")
          .withUrlParam("param", "1")
          .withUrlParam("param", "2");
      

      基本上,我是通过 POJO 创建数据库的。有点hackish但有效。但也许使用自定义密码创建 root 用户是一个更好的解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-16
        • 1970-01-01
        • 1970-01-01
        • 2022-01-25
        • 2021-02-26
        • 1970-01-01
        • 2018-11-06
        • 2018-09-17
        相关资源
        最近更新 更多