Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a good workflow for database migration in Grails?

I want to use the database-migration grails plugin for database migration. When I start my Grails app the first time all the database tables are created automatically. The production setting in my DataSource.groovy is:

production {


    dataSource {
        dbCreate = "update"
        url = "jdbc:mysql://localhost/myapp?useUnicode=yes&characterEncoding=UTF-8"
        username = "test"
        password = "test"
        dialect = org.hibernate.dialect.MySQL5InnoDBDialect
        properties {
           validationQuery = "select 1"
           testWhileIdle = true
           timeBetweenEvictionRunsMillis = 60000
        }
    }
}

In my config.groovy I set:

grails.plugin.databasemigration.updateOnStart = true
grails.plugin.databasemigration.updateOnStartFileNames = ['changelog.groovy']

When I add properties to my domain classes I need to adjust the changelog file. What is the best way to do database migration in this case? What are the steps I have to do when I add or remove columns?

like image 661
confile Avatar asked Dec 21 '12 10:12

confile


People also ask

How do you schema migration?

Migrations are performed programmatically by using a schema migration tool. When invoked with a specified desired schema version, the tool automates the successive application or reversal of an appropriate sequence of schema changes until it is brought to the desired state.

What is ORM migration?

ORM is the bridge between the API and database. Changing the entity — aka data model (TypeORM class that stores an object's state in the database) — will update the schema during synchronization or migration.

What is an advantage of supporting migration of existing tables ORM?

What are the advantages of migration tools? Migrations are helpful because they allow database schemas to evolve as requirements change. They help developers plan, validate, and safely apply schema changes to their environments.


2 Answers

As you're probably aware, the dbcreate directive is not recommended for production use:

You can also remove the dbCreate setting completely, which is recommended once your schema is relatively stable and definitely when your application and database are deployed in production.

So keep in mind that you will need to remove this (or set to 'none').


Initial Baseline Workflow

  1. Define current state
  2. Create database from change log or mark as up-to-date
  3. Set config options

The first step is to get the changelog to reflect the current state. If you've got an existing database, you want to use that to define the baseline. Otherwise, use GORM to define the tables.

These commands will generate a baseline for your database. Also I choose to use the groovy DSL format rather than liquibase XML, because readability.

Existing Database

If you've got a production database with data already, its a little bit tricky. You will need to access the database or a copy of it from your grails environment. If you manipulate a copy, you will need to apply the updates back to your production (and potentially manage it as a planned outage).

The command is:

grails [environment] dbm-generate-changelog changelog.groovy

...where environment optionally specifies the dev/test/prod/custom environment the database is defined as.

Following that, mark the database as 'up-to-date' with regards to the changelog:

grails [environment] dbm-changelog-sync

Then reapply the database to production, if neccesary.

New Database

If you don't have an existing database (or don't care):

grails dbm-generate-gorm-changelog changelog.groovy

Then, to create the database from the changelog:

grails [environment] dbm-update

Configuration

You've already correctly got the options set:

grails.plugin.databasemigration.updateOnStart = true
grails.plugin.databasemigration.updateOnStartFileNames = ['changelog.groovy']

These options simply mean that the plugin will attempt to apply the changes to the database when the application starts.


Development Workflow

  1. Make changes to domains
  2. Generate changelog identifying differences
  3. (Backup and) Update the database

So now you've got a database up-to-date, and you're smashing out changes to the domain classes, adding new ones and changing validation properties.

Each time you want to record your changes, you want to compare your GORM classes to what exists in the database, and create a new changelog file to record the difference:

grails [environment] dbm-gorm-diff [meaningful name].groovy --add

Here environment is the database you are comparing against, and meaningful name should reflect in some way the change being applied (perhaps a JIRA issue key, or a version number, or a description).

The --add flag will insert an include statement in changelog.groovy.

If you've configured updateOnStart, then you're done! Otherwise, to manually process the update, reuse the command:

grails [environment] dbm-update

RTFM

  • Plugin documentation - Getting Started
  • Plugin documentation - General Usage
  • Confile's answer above points to a good tutorial that goes into detail about manual changes to changelogs
  • Liquibase documentation - Changesets (Uses the XML format, but useful for understanding concepts)
like image 162
brasskazoo Avatar answered Oct 14 '22 18:10

brasskazoo


The approach that I would use is to migrate every table to a Grails domain with the mapping (very important!) properly set.

Then leave Grails to create the database the first time and then populate it with a previous backup of the database you want to migrate.

After this set Grails config to update the database every time it starts.

I know it seems a little bit messy but if I´ve to do it I would´ve do it this way.

Hope it helps :)

like image 1
axierjhtjz Avatar answered Oct 14 '22 18:10

axierjhtjz