# README
postgres
go wrappers, migrations, and testcontainers for postgres
🏗️ testcontainers
Testcontainers provides a container setup process from within the go application.
Because Linux requires root (or special permissions) for the Docker socket, it may be necessary to run sudo to run tests. Because sudo
may not have go install added to PATH
, use $(which go)
to pass the full path of the go command. This is not necessary for CI tests, which have preconfigured permissions to the Docker socket.
sudo $(which go) test -v
⚙️ migrations
Files for initailizing (and tearing down) a database are included in the Migrations()
function. See example-migrations
for examples.
[!TIP] Migrations files should be numbered in the order they are to be run, first
down
, thenup
. As such, alldown
migrations should be odd; allup
migrations should be even. Migrations will return a list ofMigration
objects, containing Direction, Filename, and Content.
usage
Use either local
or embed
filesystems to produce a slice of Migration
s
// Migrations represents a single SQL migration file,
// including the direction, file name, and content
type Migration struct {
Direction string
Filename string
Content string
}
local
For a local filesystem, just provide the path.
migrations, err := Migrations(os.DirFS("."), "migrations-dir-name", "up")
if err := nil {
return fmt.Errorf("migration failed: %w", err)
}
embed
For an embed filesystem, provide the embed.FS
and a filename.
//go:embed migrations
var migrationsDirEmbed embed.FS
migrations, err := Migrations(migrationsDirEmbed, "migrations-dir-name", "up")
if err := nil {
return fmt.Errorf("migration failed: %w", err)
}
applying migrations
Loop over the migrations to apply them to your database.
for _, m := range migrations {
log.Info("running migration",
"file", m.Filename,
"direction", m.Direction,
)
err := sql.Execute(m.Content)
if err != nil {
return fmt.Errorf("sql error on migration: %w", err)
}
}