postgresqlgopsqltestcontainers

Why does `.WithInitScripts` not run my SQL files?


Description

I am using a test Postgres container (from testcontainers) for more accurate integration tests. To prevent repeating code, I want to use my existing SQL migration files to setup the container, but I am encountering this error:

init.go:59: failed to add fixture 2db86489-a1e0-4364-8954-a6215f68b99a: ERROR: relation "public.account" does not exist (SQLSTATE 42P01)

Background

My code structure looks like this:

.
└── database/
    ├── migrations/
    │   ├── 000001_create_account_table.up.sql
    │   └── 000001_create_account_table.down.sql
    └── testcontainers/
        └── init.go

In init.go, I have a InitTestContainer() func that gets the *.up.sql files like so:

migrationFiles, err := filepath.Glob("../migrations/*.up.sql")

Then I pass it to the test container creation:

cntr, err := postgres.Run(ctx,
    "postgres:17.5-alpine",
    postgres.WithInitScripts(migrationFiles...),
    postgres.WithDatabase("test"),
    postgres.WithUsername("user"),
    postgres.WithPassword("pass"),
    postgres.WithSQLDriver("pgx"),
    postgres.BasicWaitStrategies(),
)

This step doesn't error, but when I run my populate function (below), the error appears.

_, err := conn.Exec(ctx, queries.CreateAccount, <args here>)

Why is this happening?


Update

After more debugging, filepath.Glob wasn't returning any files. Now I am trying to point to the folder like this:

migrationDir := filepath.Join("..", "migrations", "000001_create_account_table.up.sql")
    fmt.Printf("migrations dir: %s\n", migrationDir)

That is producing this log:

migrations dir: ../migrations/000001_create_account_table.up.sql

And no this error:

init.go:31: failed to create test Postgres container: generic container: create container: created hook: can't copy ../migrations/000001_create_account_table.up.sql to container: open ../migrations/000001_create_account_table.up.sql: no such file or directory

From the docs, I can see that the files are mount under /docker-entrypoint-initdb.d, I'm assuming the whole directory is mounted - that could be wrong tho.


Solution

  • Solution

    I realised that the path needed to be relative from where the init function was being call - maybe obvious, but took a while for me to realise. The test function was called a few levels under my internal dir (which was on the same level as the database dir in the question. I just have to: ../../ and so on until I got to the correct level.