Вопрос

The goal - in a single deploy/restart, I want to create a new table and populate some records, as there will be code changes that expect this data to be there.

The ideal - to write a migration that accomplishes this. Imagine that I've created my Foo class, generated a migration that creates the foo table with grails dbm-gorm-diff ...., and run the migration with grails dbm-update. I now have both my domain class and my database table. Cool.

Now I'll write a new migration that populates the table.

databaseChangeLog = {
    changeSet(author: "samslotsky", id: "PopulateFooTable") {
        grailsChange {
            change {
                new Foo(bar: 'baz').save()
                new Foo(bar: 'blitz').save()
            }
        }
    }
}

And I'll add that to the changelog.groovy

include file: 'populate-foo-table.groovy'

After running grails dbm-update again, there are no records in my foo table. It's not a validation issue because I can create Foo objects just fine from application code. I'm not even sure how to tell whether or not my migration has been executed, since breakpoints don't seem to catch within migrations.

So I suppose there are two good questions to ask:

  1. Besides looking for side effects (i.e. my db table being populated), how can I be sure that my migration has even executed?
  2. How can I create new records from a migration? Can I use Groovy code, or am I stuck writing SQL?

I realize that I could create the table and domain class first, deploy it, create an import tool or admin interface to seed the data, and then modify the code to consume the data. I really don't want to go through all of that. I should be able to do this seamlessly, with a single deploy, like I would in Rails.

Thanks!

Это было полезно?

Решение

Heres an example of my actual migration than ran and worked:

changeSet(author: 'me', id: 'createCodeTrees') {
    grailsChange {
        change {
            new CodeTree(name: 'BAN8', enabled: true, defaultTree: true).save(failOnError: true)
            new CodeTree(name: 'BAN8OLD', enabled: true, defaultTree: false).save(failOnError: true)
            new CodeTree(name: 'BANPPRD', enabled: true, defaultTree: false).save(failOnError: true)
            new CodeTree(name: 'BANADVM', enabled: true, defaultTree: false).save(failOnError: true)
            new CodeTree(name: 'BANSTFA', enabled: true, defaultTree: false).save(failOnError: true)
            new CodeTree(name: 'BANHRPY', enabled: true, defaultTree: false).save(flush: true, failOnError: true)
        }
    }

Другие советы

To my knowledge, here are the answers to your questions:

Per the documentation, you can execute Groovy code and an instance of groovy.sql.SQL is injected for you to execute SQL statements. You would want to do something like the following:

 databaseChangeLog = {
        changeSet(author: "samslotsky", id: "PopulateFooTable") {
            grailsChange {
                change {
                    sql.execute("insert into foo (bar) values ('baz')")
                    sql.execute("insert into foo (bar) values ('blitz')")
                }
            }
        }
    }

You can look in the DATABASECHANGELOG table to determine if specific changesets have been executed. There's even a controller available to view this via HTML.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top