Flyway 输出到 SQL 文件

发布于 2024-11-30 15:04:37 字数 51 浏览 0 评论 0原文

是否可以将数据库迁移输出到 SQL 文件,而不是直接调用 Flyway 中的数据库更改?

Is it possible to output the db migration to an SQL file instead of directly invoking database changes in flyway?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情感失落者 2024-12-07 15:04:37

大多数情况下不需要这样做,因为使用 Flyway 时数据库迁移本身已经用 SQL 编写。

Most times this will not be needed as with Flyway the DB migrations themselves will already be written in SQL.

So要识趣 2024-12-07 15:04:37

是的,这是可能的,而且就我而言,对于不想在产品中允许 Flyway 的 DBA 来说,该功能绝对是必须的。

我从这里修改了代码,这是flyway的一个试运行命令,您可以添加文件编写器并写出migrationDetails:

https://github.com/killbill/killbill/commit/996a3d5fd096525689dced825eac7a95a8a7817e

我是这样做的...项目结构(只是将其从killbill的项目中复制出来并将包重命名为flywaydr:

.
./main
./main/java
./main/java/com
./main/java/com/flywaydr
./main/java/com/flywaydr/CapturingMetaDataTable.java
./main/java/com/flywaydr/CapturingSqlMigrationExecutor.java
./main/java/com/flywaydr/DbMigrateWithDryRun.java
./main/java/com/flywaydr/MigrationInfoCallback.java
./main/java/com/flywaydr/Migrator.java
./main/java/org
./main/java/org/flywaydb
./main/java/org/flywaydb/core
./main/java/org/flywaydb/core/FlywayWithDryRun.java

在Migrator.java add(实现回调并将其放入DbMigrateWithDryRun.java) :

  } else if ("dryRunMigrate".equals(operation)) {
      MigrationInfoCallback mcb = new MigrationInfoCallback();
      flyway.dryRunMigrate();
      MigrationInfoImpl[] migrationDetails = mcb.getPendingMigrationDetails();

      if(migrationDetails.length>0){              
          writeMasterScriptToFile(migrationDetails);
      }
 }

然后编写一些东西来归档,例如:

private static void writeMasterScriptToFile(MigrationInfoImpl[] migrationDetails){

    FileWriter fw = null;
    try{
        String masterScriptLoc="path/to/file";

        fw = new FileWriter(masterScriptLoc);
        LOG.info("Writing output to " + masterScriptLoc);
        for (final MigrationInfoImpl migration : migrationDetails){
             Path file =Paths.get(migration.getResolvedMigration().getPhysicalLocation());
             //if you want to copy actual script files parsed by flyway
             Files.copy(file, Paths.get(new StringBuilder(scriptspathloc).append(File.separator).append(file.getFileName().toString()).toString()), REPLACE_EXISTING);


        }
             //or just get the sql
             for (final SqlStatement sqlStatement : sqlStatements) {  
                  //sqlStatement.getSql();  
             }
        fw.write(stuff.toString());
    } catch(Exception e){
            LOG.error("Could not write to file, io exception was thrown.",e);
    } finally{
            try{fw.close();}catch(Exception e){LOG.error("Could not close file writer.",e);}
    }

}

最后一件事要提的是,我通过maven(谷歌程序集插件+带有依赖项的jar)将其编译并打包到“带有依赖项”的jar(又名fatjar)中并运行它通过如下命令,或者您可以将其作为依赖项包含并通过 mvn exec:exec 目标调用它,这也是我取得成功的方法。

$ java -jar /path/to/flywaydr-fatjar.jar dryRunMigrate -regular.flyway.configs -etc -etc  

Yes it's possible and as far as I am concerned the feature is an absolute must for DBAs who don't want to allow flyway in prod.

I made do with modifying code from here, it's a dry run command for flyway, you can add a filewriter and write out migrationDetails:

https://github.com/killbill/killbill/commit/996a3d5fd096525689dced825eac7a95a8a7817e

I did it like so... Project structure (just copied it out of killbill's project and renamed package to flywaydr:

.
./main
./main/java
./main/java/com
./main/java/com/flywaydr
./main/java/com/flywaydr/CapturingMetaDataTable.java
./main/java/com/flywaydr/CapturingSqlMigrationExecutor.java
./main/java/com/flywaydr/DbMigrateWithDryRun.java
./main/java/com/flywaydr/MigrationInfoCallback.java
./main/java/com/flywaydr/Migrator.java
./main/java/org
./main/java/org/flywaydb
./main/java/org/flywaydb/core
./main/java/org/flywaydb/core/FlywayWithDryRun.java

In Migrator.java add (implement callback and put it in DbMigrateWithDryRun.java) :

  } else if ("dryRunMigrate".equals(operation)) {
      MigrationInfoCallback mcb = new MigrationInfoCallback();
      flyway.dryRunMigrate();
      MigrationInfoImpl[] migrationDetails = mcb.getPendingMigrationDetails();

      if(migrationDetails.length>0){              
          writeMasterScriptToFile(migrationDetails);
      }
 }

Then to write stuff to file something like:

private static void writeMasterScriptToFile(MigrationInfoImpl[] migrationDetails){

    FileWriter fw = null;
    try{
        String masterScriptLoc="path/to/file";

        fw = new FileWriter(masterScriptLoc);
        LOG.info("Writing output to " + masterScriptLoc);
        for (final MigrationInfoImpl migration : migrationDetails){
             Path file =Paths.get(migration.getResolvedMigration().getPhysicalLocation());
             //if you want to copy actual script files parsed by flyway
             Files.copy(file, Paths.get(new StringBuilder(scriptspathloc).append(File.separator).append(file.getFileName().toString()).toString()), REPLACE_EXISTING);


        }
             //or just get the sql
             for (final SqlStatement sqlStatement : sqlStatements) {  
                  //sqlStatement.getSql();  
             }
        fw.write(stuff.toString());
    } catch(Exception e){
            LOG.error("Could not write to file, io exception was thrown.",e);
    } finally{
            try{fw.close();}catch(Exception e){LOG.error("Could not close file writer.",e);}
    }

}

One last thing to mention, I compile and package this into a jar "with dependencies" (aka fatjar) via maven (google assembly plugin + jar with dependencies) and run it via command like below or you can include it as a dependency and call it via mvn exec:exec goal, which is something I had success with as well.

$ java -jar /path/to/flywaydr-fatjar.jar dryRunMigrate -regular.flyway.configs -etc -etc  
终止放荡 2024-12-07 15:04:37

我没找到办法。改用mybatis迁移。看起来相当不错。

I didnt find a way. Switched to mybatis migration. Looks quite nice.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文