DB Migration Builder is a simple library to build database migration scripts; if you are unfamiliar with database migrations check out this excellent article.
Database Migrations as a concept is nothing new, but it does present significant benefits to developers, DBAs, Release Managers, Operations staff, and others. However, most tools try to do too much without really respecting segregation of duties, technology approval processes, security concerns, and auditing to name a few.
DB Migration Builder was built to provide the opportunity for use of database migrations in large organisations that require tools to undergo strict approval processes before they are approved for use. It can be quite a lengthy and arduous journey to get new tools approved in large organisations, and approval usually comes with restrictions in use of functionality.
Further, Organisations need a tool to produce migration scripts rather than to execute and manage them. The use of one tool to run manage a database state and migration scripts locks organisations into the tool and can result in staff not entirely thinking through the consequences of their actions.
Organisations need a flexible tool to produce migrations, not necessarily execute them!
DB Migration Builder was developed to address a gap in the understanding of existing tool providers, its goals are:
- construct migration scripts for individual delta (change) scripts created by users
- be flexible and extensible in the versioning structure (because each organisation is different!)
- let users customise and extend functionality through a simple API
- allow users to retain flexibility in control of the database
To use DB Migration Builder it is necessary to agree on the lingo.
Delta Scripts (also known as "change scripts") are SQL files created by users to transition a database resources (e.g. table, records, view) from one state to another. Developers write these SQL files just like they would do for any other tool!
Delta scripts can be categorized in one of the following:
- upgrade scripts
- rollback scripts
- bidirectional scripts
The upgrade and rollback scripts are self-explanatory, the bidirectional scripts are applied in both upgrade and rollback migration scripts and are typically used to perform actions such as logging.
A set of related delta scripts are pieced together to create a single migration script; migration scripts are required for both upgrade and rollback operations on a database.
A Module is a logical aggregation of related resources or a functional area of an application that is independently versioned. For example, in a large CMS, you may have packages for "revenue", "opportunities", "contacts" etc, and each release of the application may not necessarily result in changes to all these packages. Moreover, release 2.1 may have changes just for the "revenue" module but 2.2 may include changes to "revenue" and "contacts". In this case it makes sense to version each package independently and allow each to be maintained separately.
Note that modules are optional.
A Version is used to identify a certain point in the lifecycle of the application (or database scripts in this case).
The following should make it clear what each of these terms represents:
- scripts
- revenue <-- Module: "revenue"
- 1.0 <-- Version
- 0001-create-projections-table.sql <-- Delta script #1
- 0002-projects-triggers.sql <-- Delta script #2
- 1.2
- 0001-add-audit-trigger.sql
- 0002-insert-new-admin.sql
- contacts <-- Module: "contacts"
- 0.0.1
- 0001-create-customer-table.sql
- 0002-add-dummy-customer.sql
- 0.1
- 0001-add-audit-triggers.sql
- 0002-create-view-on-customer.sql
For the case where no modules are necessary (most systems) you will have the following layout:
- scripts
- 1.0 <-- Version
- 0001-create-projections-table.sql <-- Delta script #1
- 0002-projects-triggers.sql <-- Delta script #2
- 1.2
- 0001-add-audit-trigger.sql
- 0002-insert-new-admin.sql
When setting up a new project you have to decide on the versioning scheme you want to employ. Take a look at our sample projects to see working examples on how to set up your project.
Steps:
- Create the
change_log
table for your database - Select your versioning scheme, one of:
standard
,semver1
- Create your delta scripts for the version that you want to release
- Run the migration script as per the following section
- Take the produced SQL migration script and execute it on your database
If you use DB Migration Builder we'd love to hear from you and give your company/team a plug on our page! Any information such as company name, team size, etc would help us shape this product.
The most common way to use DB Migration Builder is via a plugin, and we have maven and gradle plugins available. Check out the respective pages for details on how to use DB Migration Builder via those plugins.
Take a look at our sample projects on how to set up your directory structure.
If you prefer to use DB Migrations Builder manually or via a ant script read on.
- Download the latest build: TODO: - set URL
- Unzip the file into your preferred location, we'll refer to this as
DBMIG_HOME
- Run
$DBMIG_HOME/db-migration.sh
with the relevant parameters
The following parameters are available:
Usage: db-migration.sh
[-d <database>] the type of database to generate migrations for
[-i <input directory>] the path to the input directory containing the modules/versions
[-o <output directory>] the path to the output directory to write to
[-v <version>] [optional] the version to be processed
[-k <version scheme>] [optional] the scheme by which the versions abide
[-m <module1, module2, ..., moduleN>] [optional] the names of the modules to be processed as a CSV string
At the time of this writing the databases that come with out-of-the-box support are mysql
and mssql
, but you can
very easily add support for other databases. Read the section on Customizing DB Migrations Builder [TODO - provide link]
to find out how to add support for other databases, but don't forget to share your work
so we can add it into the core build for everyone to use!
The path to the input directory that contains either the modules or the versions to be processed.
The path to the output directory to write the generated migration scripts to.
Optional - the version to generate migration scripts for. If omitted the latest version in the input directory (or module) will have migration scripts generated for.
Note that the version must match the name of the directory (i.e. version!) that you wish to generate scripts for.
Optional - the name of the versioning scheme used, and this must match the in either the default configuration or in your config file override.
The schemes supported in the bundled default configuration are default-standard
and default-semver1
, with the default
being default-standard
; refer to the section on customization if you wish to build your own scheme.
The application comes bundled with default configuration, to control application behaviour.
The configuration contains settings to control:
- application controls and preferences
- database settings
- version schemes
To create your own configuration you can start by copying the default configuration
into your very own $DBMIG_HOME/conf/config.yaml
file and change the fields as necessary.
To add support for a database engine that is not bundled into the application (e.g. foodb
) create a sub-element
beneath database\engine
and change the values as desired.
# Database preferences and settings.
database:
# Engine-specific settings.
engine:
foodb:
# The name of the change-log table to be written to; default = 'change_log'.
change-log-table-name: 'change_log'
# The value for the delimiter to be written between statements.
db-statement-delimiter: 'GO'
# The value for the separator to be written between statements.
db-statement-separator: ''
If you add support for a new database then you need to create a new set of templates for piecing together the individual delta scripts into overall change scripts; you can find the templates for the database that have support at this time here.
To add a set of new templates for our new database engine (foodb):
- create a directory to store your new templates, we recommend using:
$DBMIG_HOME/conf/templates/foodb
- copy one of the built-in supported database templates into this directory
- make changes to the templates that you desire
- modify the
template-override-directory
in the config.yaml file to contain the full path to the override directory, which in this case is$DBMIG_HOME/conf/templates
You can control application behaviour by altering the values of the fields beneath general
; each field has a
description to help you set an appropriate value.
There are two versioning schemes bundled into the product, standard
and semver1
(aka Semantic Versioning 1). For a
complete discussion of versioning schemes refer to the sections below.
The out-of-the-box functionality bundled into the application is discussed below, along with information on how to alter this behaviour. Take a look at the sample projects to see how customization can be done.
There are two versioning schemes bundled into the product, standard
and semver1
(aka Semantic Versioning 1).
The standard versioning scheme
uses between 2 and 4 digits and an optional release tag to represent a version number.
The version number component
of the scheme accepts between 2 and 4 digits to represent ${prefix}${prefix-separator}${major}.${minor}.${build}.${revision}
and the (optional)
pre-release tag component
represents ${tagName}-${tagNumber}
.
Between two and four digits can be used to capture the version number to represent the following components of the version number:
- Major release number
- Minor release number
- Build number (optional)
- Revision number (optional)
You can specify an optional prefix and separator strings to prepend the version number.
The pre-release tag component of the standard versioning scheme provides the ability to capturerelease milestones (tags), such as
- Alpha version
- Beta version
- Release candidate
along with an associated tag number; thus you can have alpha-1
and rc-2
tags.
The default configuration provides settings to support versions such as:
- 1.0
- 2.1.23
- 5.3.2.11
- 1.1-alpha-1
- 2.3.4-beta-2
- 3.2.94.33-rc-8
Note that:
- no prefix/prefix separator is set
- the
.
(dot) character is the number separator - the
-
is the separator between the version and pre-release tag - the
-
is the separator between the pre-release tag and tag number
and this is captured with the following version scheme configuration:
# Defines the settings for the default versioning scheme used in the application.
default-standard:
# The name of this versioning scheme; this must correspond to an application-supported scheme.
scheme: standard
# The prefix string that prepends the version number for the standard version scheme.
prefix: ''
# The string that separates the prefix and version number for the standard version scheme.
prefix-separator: ''
# The string that separates the digits in the version number for the standard version scheme.
digit-separator: '.'
# The string that separates the version number from the tag for the standard version scheme.
tag-separator: '-'
# The string that separates the tag pre-release tag from the (tag) sequence number for the standard version scheme.
tag-sequence-separator: '-'
To customise this versioning scheme create your own config.yaml
file as per the prior sections. As an example if
we want to support versions such as r:3-2-94-33_rc^8
the following configuration is required.
# Defines the settings for a custom version based off the standard version scheme.
my-awesome-version:
# The name of this versioning scheme; this must correspond to an application-supported scheme.
scheme: standard
# The prefix string that prepends the version number for the standard version scheme.
prefix: 'r'
# The string that separates the prefix and version number for the standard version scheme.
prefix-separator: ':'
# The string that separates the digits in the version number for the standard version scheme.
digit-separator: '-'
# The string that separates the version number from the tag for the standard version scheme.
tag-separator: '_'
# The string that separates the tag pre-release tag from the (tag) sequence number for the standard version scheme.
tag-sequence-separator: '^'
Another scheme that is implemented in the engine is (partial) semantic versioning 1 and contains the following components of the version number:
- Major release number
- Minor release number
- Patch number
- Release timestamp
The default configuration
provides settings to support versions such as 1.0.3+20180330210358
.
Note that:
- the
.
(dot) character is the number separator - the
+
is the separator between the version and release timestamp
and this is captured with the following version scheme configuration:
version-schemes:
# The default semver1 config.
default-semver1:
# The name of this versioning scheme; this must correspond to an application-supported scheme.
scheme: semver1
# The string that separates the digits in the version number for the standard version scheme.
digit-separator: '.'
# The format of the date component of the version.
date-format: yyyyMMddHHmmss
# The string that separates the digits from the date portion of the scheme.
date-separator: '+'
To customise this versioning scheme create your own config.yaml
file as per the prior sections. As an example if
we want to support versions such as 1_0_3:20180330210358
. the following configuration is required.
version-schemes:
# Custom semver1 configuration.
my-awesome-semver1:
# The name of this versioning scheme; this must correspond to an application-supported scheme.
scheme: semver1
# The string that separates the digits in the version number for the standard version scheme.
digit-separator: '_'
# The format of the date component of the version.
date-format: yyyyMMddHHmmss
# The string that separates the digits from the date portion of the scheme.
date-separator: ':'
You can modify the date-format
to any pattern that is supported in the Java date format specification.
Templates are built into the engine to support mysql and mssql at the time of this writing, support for additional databases is on the agenda though.
The default templates contain 3 files:
- upgrade_template.txt: specifies the structure to embed the individual delta upgrade scripts in to compose the overall migration upgrade script
- rollback_template.txt: specifies the structure to embed the individual delta rollback scripts in to compose the overall migration rollback script
- bidirectional_template.txt: specifies the structure to embed the individual delta scripts in to compose both the upgrade and rollback migration scripts.
Once you create a new set of templates for your database you need to specify the path to this folder in your very own
config.yaml
file; refer to the section on adding a new database for further information.
You can extend DB migration builder and add custom functionality quite easily, this page contains details on how to customize and extend the application.
This is open-source software and you are free to use it in any way you like under the Apache 2 License.
If you'd like to add functionality, extend behaviour or fix a bug feel free to raise an issue or pull request.