【问题标题】:Can you use Groovy code to create and modify data in a Grails migration?您可以使用 Groovy 代码在 Grails 迁移中创建和修改数据吗?
【发布时间】:2013-05-20 06:28:03
【问题描述】:

目标 - 在一次部署/重新启动中,我想创建一个新表并填充一些记录,因为会有代码更改期望这些数据存在。

理想的 - 编写完成此任务的迁移。想象一下,我创建了我的Foo 类,生成了一个使用grails dbm-gorm-diff .... 创建foo 表的迁移,并使用grails dbm-update 运行迁移。我现在有我的域类和我的数据库表。很酷。

现在我将编写一个填充表的新迁移。

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

我会将它添加到 changelog.groovy

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

再次运行grails dbm-update 后,我的foo 表中没有记录。这不是验证问题,因为我可以从应用程序代码中创建 Foo 对象。我什至不确定如何判断我的迁移是否已执行,因为断点似乎没有在迁移中捕获。

所以我想有两个很好的问题要问:

  1. 除了寻找副作用(即填充我的数据库表)之外,我如何确定我的迁移甚至已经执行?
  2. 如何从迁移中创建新记录?我可以使用 Groovy 代码吗?还是我一直在写 SQL?

我意识到我可以先创建表和域类,部署它,创建导入工具或管理界面来播种数据,然后修改代码以使用数据。我真的不想经历所有这些。我应该能够像在 Rails 中那样,通过一次部署无缝地做到这一点。

谢谢!

【问题讨论】:

  • 在 Bootstrap 中创建记录?
  • @JamesKleeh:我认为 Bootstrap 不能在生产环境中运行。
  • Bootstrap 应该在生产环境中运行 - 我一直使用它来做到这一点。
  • @Samo 如果使用 Liquibase,MigrationCallbacks 不应该在这里有用。抓取数据源并在afterMigrations回调中添加项目?
  • @Samo - Bootstrap 在生产中运行

标签: grails migration grails-2.0 seeding


【解决方案1】:

这是我实际迁移的一个示例,而不是运行和工作:

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)
        }
    }

【讨论】:

  • 谢谢 - 知道它适用于其他人帮助我选择了追求的方向!
  • 在迁移中使用域类是不好的做法,因为如果域发生变化,代码可能会中断。
【解决方案2】:

据我所知,以下是您问题的答案:

根据documentation,您可以执行Groovy 代码并注入一个groovy.sql.SQL 实例供您执行SQL 语句。您可能希望执行以下操作:

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

您可以查看 DATABASECHANGELOG 表以确定是否已执行特定变更集。甚至还有一个 controller 可以通过 HTML 来查看。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-07
    • 2021-10-09
    • 2017-05-26
    • 2012-11-02
    • 2014-12-01
    • 1970-01-01
    • 2015-03-14
    • 2011-02-15
    相关资源
    最近更新 更多