6

How I can create multiple database on one mysql db container? Or Do I have to create db container per database? When I am trying to create it from sql file script:

    @ClassRule public static MySQLContainer dbService = (MySQLContainer) new MySQLContainer()
        .withPassword("test")
        .withUsername("mysqlroot")
        .withDatabaseName("test")
        .withInitScript("init_mysql.sql")
        .withExposedPorts(DB_PORT)
        .withNetwork(network)
        .withNetworkAliases("dbService")
        ;

I am getting an error:

Caused by: org.testcontainers.ext.ScriptUtils$ScriptStatementFailedException: Script execution failed (init_mysql.sql:2): CREATE DATABASE IF NOT EXISTS `b2c`
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:331)
... 19 more
Caused by: java.sql.SQLSyntaxErrorException: Access denied for user 'mysqlroot'@'%' to database 'b2c'
    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)
    ... 21 more

content of init_mysql.sql

CREATE TABLE bar (
    foo VARCHAR(255)
);
CREATE DATABASE  IF NOT EXISTS `b2c`;

I've tried many configuration. For me it seems that I can not execute sql except dedicated database configured on container creation. Please help. I have 6 DB and It is waste of resources to created dedicated container for each one.

masterdany88
  • 5,041
  • 11
  • 58
  • 132
  • Did you try using 'Using an init script from a file' method mentioned here: https://www.testcontainers.org/modules/databases/. You get a connection passed to your init function and you can just run all your scripts (example: creating your 6 DBs) there. – chom Aug 07 '19 at 22:24

1 Answers1

4

First you need to start your MySQLContainer with root username (in order to have privileges to execute your init script):

        new MySQLContainer<>(new DockerImageName(MYSQL_DOCKER_IMAGE))
            .withUsername("root")
            .withPassword("")
            .withEnv("MYSQL_ROOT_HOST", "%")
            .withInitScript("init_test_container_databases.sql")
            .withNetwork(NETWORK)
            .withNetworkAliases(MYSQL_NETWORK)
            .withStartupTimeout(Duration.ofSeconds(CONTAINER_STARTUP_TIMEOUT_SECONDS));

init_test_container_databases.sql script (in my example I create two databases with same user which will be used by my app):

CREATE DATABASE IF NOT EXISTS your_database_1;
CREATE DATABASE IF NOT EXISTS your_database_2;
CREATE USER 'your_username'@'%' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON *.* TO 'your_username'@'%';
Lucian Radu
  • 302
  • 1
  • 4
  • 17