Rivet is a database migration/change management/versioning tool inspired by Ruby on Rails' Migrations. You write PowerShell migration scripts that describe the changes you want to make to a SQL Server database, e.g. add a table, add a column, drop an index, etc. Rivet applies those scripts to a database, bringing its schema up-to-date.
To get started, download Rivet from the PowerShell gallery:
> Save-Module -Name 'Rivet' -Path '.'
This will save Rivet into a Rivet directory in your current directory. (If you're running PowerShell 4, you'll need to download and install PowerShell Package Management Modules Preview.)
You can also download a ZIP file from the Rivet project's GitHub page. Unzip the file, and drag the Rivet directory where you'd like it.
Next, you'll need to create a rivet.json
file that contains a connection
string to your database and the path where you want to keep your migration
scripts. The simplest configuration file looks like this:
{
SqlServerName: '.\Rivet',
DatabasesRoot: 'Databases'
}
With this configuration file, Rivet will connect to the SQL Server at .\Rivet
and will look for migration scripts in Databases\DATABASE_NAME\Migrations
.
Now you can create your first migration. Run:
> .\Rivet\rivet.ps1 -New -Database DATABASE_NAME -Name 'MyFirstMigration'
Rivet will create a migration at
Databases\DATABASE_NAME\Migrations\20170625132040_MyFirstMigration.ps1
. The
migration's filename has two parts: an ID (e.g. 20170625132040
followed by the
migration's name. Rivet uses the ID to track what migrations have been applied
to a database.
Open the migration in your favorite PowerShell text editor. We recommend the
PowerShell ISE, because of its intellisense and debugging capabilities. (To get
Intellisense as you type, import Rivet first: Import-Module '.\Rivet'
.)
You'll see two functions: Push-Migration
and Pop-Migration
. In the
Push-Migration
function, you'll add Rivet operations that modify your
database. In the Pop-Migration
function, you'll add operations that
reverse/rollback the changes made in Push-Migration
.
Let's create a table:
function Push-Migration
{
Add-Table -Name 'MyFirstTable' -Column {
int 'id' -Identity
}
}
function Pop-Migration
{
Remove-Table -Name 'MyFirstTable'
}
To apply your migration to your database, run rivet.ps1
with its -Push
switch:
> .\Rivet\rivet.ps1 -Push
Look in your database and it will contain the MyFirstTable
table. By default,
pushing migrations pushes them to all your databases. If you only want to push
to a single or specific databases, use Rivet's Database
parameter:
> .\Rivet\rivet.ps1 -Push -Database 'DATABASE_NAME'
To reverse/rolllback your migration run rivet.ps1
with the Pop
switch:
> .\Rivet\rivet.ps1 -Pop
This will pop the newest migration in each database's Migrations
directory.
(Use the Database
parameter to pop the newest migration from specific
databases.) Look in your database, and the MyFirstTable
database is gone.
Next, let's add another column to our table:
function Push-Migration
{
Add-Table -Name 'MyFirstTable' -Column {
int 'id' -Identity
nvarchar 'name' 50 -NotNull
}
}
You didn't have to modify the Pop-Migration
function because it removes the
table, so you don't need to remove each column. As you work on your migration,
you'll be changing your Push-Migration
function to get it just right. You'll
have to do a lot of pushing and popping. Rivet has a special Redo
switch that
does a pop followed by a push:
> .\Rivet\rivet.ps1 -Redo
After you run this command, look in your database and you'll see that the
MyFirstTable
table now has a name
column.
Once your migration is done, commit it to your source control repository. Once you make your migration available to others, it is immutable and should never be changed. Rivet applies migration scripts as an entire unit. It uses each migration's ID to determine if that migration has been applied to a database. If it has been applied, Rivet skips it and moves on to the next migration. So, if you modify a migration after it's public, that change will never get applied anywhere. If you need to change a public migration, create a new migration that makes the changes you need.
Rivet wraps all pushes and pops in a transaction. If any part of a migration fails, the entire transaction is rolled back. Your database will never be left in a state where part of a migration is applied.
To see a full list of operations, run this command:
> Get-Command -Module 'Rivet'
Or, visit the Documentation page at the https://get-rivet.org website.
See the about_Rivet_Configuration topic for details on configuring Rivet in
the rivet.json
file.
The about_Rivet_Plugins topic explains how to write your own Rivet operations.