Skip to content

Instantly share code, notes, and snippets.

@shanna
Last active May 23, 2016 06:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shanna/058e88877fc1c47db678f70fad239c90 to your computer and use it in GitHub Desktop.
Save shanna/058e88877fc1c47db678f70fad239c90 to your computer and use it in GitHub Desktop.
Postgres migration script.
#!/usr/bin/env sh
set -eu
if [ $# -ne 0 ]; then
cat <<-USAGE
psql-migrate
Takes a sorted list of filenames from stdin and writes psql migrations sql
to stdout.
usage:
ls -1v migrations/* | psql-migrate | psql ...
safety:
* A migration table called 'schema_migrations' will be created.
* Paths passed to stdin must be relative to the script or absolute.
* Only migration file basenames are persisted in schema_migrations.
USAGE
exit 0
fi
migrations=""
while read -r migration; do
if [ ! -r "$migration" ]; then
echo "error: '$migration' not readable."
[ "$migration" = "$(basename "$migration")" ] && echo "Did you forget to include the path?"
exit -1
fi
migrations="${migrations} $migration"
done < /dev/stdin
cat <<-SQL
\set ON_ERROR_STOP ON
create table if not exists schema_migrations (
migration text not null primary key,
completed timestamp with time zone not null default now()
);
SQL
for migration in $migrations; do
filename=$(basename "$migration")
cat <<-SQL
-- begin migration $filename
do \$$
begin
perform 1 from schema_migrations where migration = '$filename';
if not found then
raise notice 'migration "%", begin', '$filename';
-- begin sql
$(cat "$migration")
-- end sql
insert into schema_migrations values ('$filename');
raise notice 'migration "%", end', '$filename';
else
raise notice 'migration "%" already run, skipping', '$filename';
end if;
end
\$$;
-- end migration $filename
SQL
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment