Runs database deltas in order of semver and adds some nice plpgsql functions to help facilitate migrations.
When you just need some simple database migrations done, it's useful to run a plpgsql delta script. Why use plpgsql instead of using your own scripting language of choice? Plpgsql scripts are run as a transaction automatically, so you don't have to worry about messing things up during development of your delta script. Also, being able to easily utilize SQL in the scripting language is a huge plus.
Install:
npm install pg-delta
Usage:
Setup a directory with your delta scripts:
db/
deltas/
- 1.0.0.sql
- 1.0.1.sql
- 1.0.2.sql
In a script, require the delta module and call run
.
var delta = require('pg-delta');
var options = {
connectionParameters: MY_POSTGRES_CONN_STR
, deltasDir: './db/deltas'
};
delta.run( options, function( error ){
/* ... */
});
Note that the pg-delta module is also an EventEmitter
.
Run the deltas specified in the directory options.deltasDir
in order of semver.
Required Options:
{
// Postgres connection string
connectionParameters: 'postgres://localhost/my_db'
// Directory in which your delta scripts live
, deltasDir: './db/deltas'
}
Optional Options and Defaults:
{
// Query used to select deltas already run
deltasQuery: 'select * from deltas'
// Extension for deltas file
, deltaExtension: 'sql'
// Path for setup script
, setupPath: path.join( __dirname, 'setup.sql' )
}
Checks whether a table exists
Reads a file and executes the result as a query
var delta = require('pg-delta');
delta.on( 'before:delta', function( version, file, contents ){
/* ... */
});
delta.on( 'before:delta:x.x.x', function( file, contents ){
/* ... */
});
delta.on( 'after:delta', function( version, file, contents ){
/* ... */
});
delta.on( 'after:delta:x.x.x', function( file, contents ){
/* ... */
});
-- Delta
DO $$
declare version text := '1.2.3';
begin
raise notice '## Running Delta v% ##', version;
-- Update version
insert into "deltas" ( "version" ) values ( version );
-- Add a new table
create table if not exists users ();
-- Intead of creating a table and all of its columns
-- in one statement, break up each column into its own
-- statement so you can run the script multiple times
-- and add new columns as you go
perform add_column( 'users', 'id', 'serial primary key' );
perform add_column( 'users', 'email', 'text' );
perform add_column( 'users', 'password', 'text' );
perform add_column( 'users', 'name', 'text' );
-- Drop constraints before adding them so script can
-- be run multiple times
if constraint_exists( 'users_email_key' )
then
alter table users drop constraing users_email_key;
end if;
alter table users add constraint users_email_key unique( "email" );
end$$;
Checks whether a table exists
Checks whether a column exists on a table
Checks whether a constraint exists by constraint name
Checks whether a constraint exists by constraint type, table, and column
Attempts to add a column to a table if the column does not already exist
Attempts to drop a column to a table if the column exists
Attempts to add a new data type if the type does not already exist