2011年11月13日 星期日

Data Migration plugin for Grails

The Problem 


    開發網站所有部分都可以非常"迅捷",但唯有在開發階段,再上線階段的資料維護造成開發綁手綁腳(db schema無法輕易更動),在此前提下第一版本的data schema必須要考慮額外周全,期望接下來只有微小的變動;在Grails採用Hibernate的ORM做資料庫的管控,但問題並沒有完全解決:
GORM dbCreate has Problems 
    If you haven't already realized it, hibernate's dbCreate feature has its problems. It does not support database migrations robustly. Some basic database changes work, such as adding a completely new table or adding new columns, but that is it. Briefly, here are some problems with dbCreate. I will leave in depth research up to the reader: Does not delete columns No conversion of datatypes.

  • No data migration

  • Cannot change a constraint on a column 

  • Cannot add a column with not-null constraint on existing table 

  • Rows read and updated will not be able to update ever again

在过去几年中,我使用过的大多数应用程序都是需要管理大量数据的企业应用程序。从事这类项目的开发团队常常将数据库视为与应用程序完全脱离的单独实体。造成这种现象的原因是组织结构经常将数据库团队从应用程序开发团队分离出来。有时候,这是团队的习惯引起的。不管怎样,我发现这种分离会导致(或忽略)一些实践: 

  • 手工变更数据库 

  • 不能与团队的其他成员分享数据库变更 

  • 使用不一致的方法变更数据库或数据 

  • 使用低效的手工方法管理数据库版本之间的变更

The Idea - 自动化 DBA


     DBA 在控制开发数据库的变更时造成了一些不必要的瓶颈。DBA 应该把时间花在一些创新的、非重复性行为,例如监视和改善数据库性能,而不是假借控制性和一致性的名义做一些无用的重复性工作。
Feature


    脚本化所有 DDL 和 DML  : 数据库变更应该能够从命令行运行。
    数据资产的源代码控制 使用一个版本控制库管理所有与数据库相关的变更。
    本地数据库沙盒 每个开发人员使用一个本地数据库沙盒执行变更。
    自动化数据库集成 将数据库相关的变更作为构建过程的一部分。

Related Tool

  • liquibase 
  • ror - data migration 
  • autobase ... 
Flowchart for liquibase


Step by Step

  1. grails create-app testDataMigration 
  2. grails install-plugin database-migration 
  3.  grails create-domain-class Person 
  4. edit Person.groovy class 
  5. Person { String name Integer age static constraints = { name() age(nullable: true) } }
  6.  grails dbm-generate-gorm-changelog changelog.groovy # build the first script by currently domain 
  7. grails dbm-changelog-sync 
  8. modify the Person.groovy class Person { String name Integer age String address // add the address filed static constraints = { name() age(nullable: true) } } 
  9. grails dbm-gorm-diff add-address-on-person.groovy --add # add the diff change 
  10. grails dbm-update #sync with DB 
Reference: