migrate icon indicating copy to clipboard operation
migrate copied to clipboard

Support environment variables in migration files using go templates

Open ninthclowd opened this issue 2 years ago • 16 comments

This PR adds a -template command line option that, when enabled, allows you to substitute any environment variables into your migration file with go templating. i.e. If you set the LOCAL_WAREHOUSE environment variable to MY_DB and have a migration file with the following contents:

                       INSERT INTO {{.LOCAL_WAREHOUSE}}.INVENTORY.RECORDS ('foo') VALUES ('bar');

it will be transformed into the following before being executed:

                       INSERT INTO MY_DB.INVENTORY.RECORDS ('foo') VALUES ('bar');

See https://pkg.go.dev/text/template for more information on supported template formats.

As mentioned in #747, this functionality could be done with envsubt, but that requires you to build custom scripts to do so. It ended up being just as much effort to add the functionality with go template and kept our pipelines and local development workflow more simple.

ninthclowd avatar Aug 16 '22 00:08 ninthclowd

Coverage Status

Coverage decreased (-0.04%) to 57.732% when pulling 3ffb53bc84aa16b8b0a2e9119d185c75969b0b01 on ninthclowd:feature/templating into 03613f14ac4f975eb0070a23958123c5d84e6b87 on golang-migrate:master.

coveralls avatar Aug 16 '22 00:08 coveralls

@dhui Can you please review this?

makeavish avatar Sep 19 '22 12:09 makeavish

@dhui it would be nice to have this functionality. Is there a chance to get it into main?

Bessonov avatar Feb 25 '23 19:02 Bessonov

This could be a very nice feature. An use case: it will allow to customize migrations files for testings pipelines that run in parallel and that requires to have different databases for each test thread to avoid conflicts.

We currently have to trick migration files with find/replace to obtain a similar feature. The template support will be very interesting.

francescorivola avatar Mar 30 '23 08:03 francescorivola

Yes, this would be a great feature to have merged into main. I'm having to do the envsubst trick right now and I think that's rather hacky.

+1

dorfire avatar Jul 09 '23 11:07 dorfire

I made this script file to run sql-migrate with env variables present in .env file:

  • This will work for mac os.
  • For linux, replace #!/bin/sh with #!/bin/bash

migrate.sh

#!/bin/sh

# Import env variables from ./.env
set -a
[ -f .env ] && . .env

echo "DB_NAME = $DB_NAME | DB_USER = $DB_USER | DB_HOST = $DB_HOST | DB_PORT = $DB_PORT"
read -p "⚡️ (Sql-Migrate) Type: <up | d | s> " command

if [[ $command == 'up' ]]
then
    sql-migrate up -env="development" sslmode=disable
elif [[ $command == 'd' ]]
then
    sql-migrate down -env="development" sslmode=disable
elif [[ $command == 's' ]]
then
    sql-migrate status -env="development" sslmode=disable
else
    read -p "Run your own command: " custom_command
    sql-migrate $custom_command -env="development" sslmode=disable
fi

smitpatelx avatar Jul 24 '23 23:07 smitpatelx

+1

dhawal1248 avatar Oct 05 '23 12:10 dhawal1248

@dhui Do you guys have a plan to approve it or we should stick with other solutions?

dorsegal avatar Jan 10 '24 10:01 dorsegal

Can we merge it into main?

yauhen-sobaleu avatar Feb 14 '24 11:02 yauhen-sobaleu

You can wrap the file when using iofs to support templating

type templateFile struct {
	data any
	fs.File
}

func (t *templateFile) Read(p []byte) (int, error) {
	_, err := t.File.Read(p)
	if err != nil {
		return 0, err
	}

	tmpl, err := template.New("").Parse(string(p))
	if err != nil {
		return 0, err
	}

	buf := new(bytes.Buffer)

	err = tmpl.Execute(buf, t.data)
	if err != nil {
		return 0, err
	}

	return copy(p, buf.Bytes()), nil
}

type templateFS struct {
	data any
	embed.FS
}

func (t *templateFS) Open(name string) (fs.File, error) {
	file, err := t.FS.Open(name)
	if err != nil {
		return nil, err
	}

	return &templateFile{t.data, file}, nil
}

hope this helps someone

nekinie avatar Feb 20 '24 16:02 nekinie

+1

y0j0 avatar Feb 29 '24 08:02 y0j0

+1

g-getsov avatar Mar 23 '24 11:03 g-getsov

@ninthclowd thanks for the contribution! I have just tested it in the latest version and it works great. It has been extremely helpful to inject some static environment values in the migrations.

offzale avatar May 16 '24 12:05 offzale

Hi, is it possible to merge this wonderful PR asap, please?

VinceHIH avatar Jul 04 '24 09:07 VinceHIH

will it be merged? may be in feature branch? just to use in my go.mod

mhthnz avatar Jul 05 '24 07:07 mhthnz