Open lukaseder opened 1 year ago
Hi @lukaseder, thanks for raising the issue.
Currently, it is recommended to use Flyway or Liquibase for database initialization. Also, most of the database images provide a directory to initialize the database. So, withCopyToContainer
and withCopyFileToContainer
can be used along with Transferable.of
, MountableFile.forClasspathResource
and MountableFile.forHostPath
. I wonder if those would help to fix your issue.
Additionally, there are many cases where the script doesn't have to be a file. An inline script in String form would suffice
Testcontainers provides Transferable
in order to achieve your need.
String schema = """
create schema test;
create table test.test (test int);
""";
...
withCopyToContainer(Transferable.of(schema), "/docker-entrypoint-initdb.d/schema.sql")
ScriptUtils.runInitScript
also has some limitations regarding sql syntax. That's the reason why our recommendation on relying to existing mechanism.
Currently, it is recommended to use Flyway or Liquibase for database initialization.
Ironically, I was looking into using testcontainers here precisely because of Flyway breaking tons of things in their upgrades, and for the use-case I had, I didn't want to debug through those breakages. The use-case is a simple example that just runs a single script containing 1 table, where Flyway (or Liquibase) would be total overkill.
I resorted to using sql-maven-plugin
, because it does the job during the build.
I understand that this init script utility isn't a top priority, because it will always be a very limited tool. Though, being able to load a file with absolute (or relative) path rather than a file from the classpath seems to be relatively simple? A lot of build tools (including Flyway and Liquibase) support both classpaths and actual paths for such things. I think this looks like a low hanging fruit. If the 2 existing Resource
lookups fail, just try checking if the path resolves to an actual java.io.File
with File::exists
, and if so, load that.
Also, most of the database images provide a directory to initialize the database. So,
withCopyToContainer
andwithCopyFileToContainer
can be used along withTransferable.of
,MountableFile.forClasspathResource
andMountableFile.forHostPath
. I wonder if those would help to fix your issue.
Appreciate the workarounds, thanks. This will be helpful for others, I'm sure. In my case, I just wanted to avoid complexity given the example is so super simple. I removed Flyway because of complexity (that wasn't essential to the example). I'm sure a lot of users will find the init script very useful for exactly this purpose: Avoiding complexity.
Module
Core
Proposal
The
ScriptUtils::runInitScript
only accepts paths from the classpath. This isn't as powerful as I would have expected given:compile
(ortest-compile
) phase must have run, but what if I want to use testcontainers in thegenerate-sources
(orgenerate-test-sources
) phase, e.g. to generate jOOQ code? In that case, the init scripts aren't available on the classpath yet, unless I create a separate module just for this, which is overkillAdditionally, there are many cases where the script doesn't have to be a file. An inline script in String form would suffice, e.g.