【问题标题】:comparing databases and generating sql script using liquibase使用 liquibase 比较数据库并生成 sql 脚本
【发布时间】:2023-04-03 21:34:02
【问题描述】:

我正在使用与 ant 集成的 liquibase 比较两个数据库。但它生成的输出就像通用格式。它没有给出 sql 语句。请谁能告诉我如何使用与 ant 或命令行实用程序集成的 liquibase 比较两个数据库。

【问题讨论】:

    标签: ant liquibase


    【解决方案1】:

    获取代表两个数据库之间差异的SQL语句是一个两步操作:

    1. 生成 XML“差异”变更日志
    2. 生成 SQL 语句

    示例

    此示例需要 liquibase.properties 文件(简化了command-line 参数):

    classpath=/path/to/jdbc/jdbc.jar
    driver=org.Driver
    url=jdbc:db_url1
    username=user1
    password=pass1
    referenceUrl=jdbc:db_url2
    referenceUsername=user2
    referencePassword=pass2
    changeLogFile=diff.xml
    

    现在运行以下命令来创建 SQL 语句:

    liquibase diffChangeLog
    liquibase updateSQL > update.sql
    

    liquibase 的一个不错的特性是它还可以生成回滚 SQL:

    liquibase futureRollbackSQL > rollback.sql
    

    更新

    Liquibase 不会在数据库之间生成数据差异,只会生成模式。但是,可以将数据库数据转储为一系列变更集:

    liquibase --changeLogFile=data.xml --diffTypes=data generateChangeLog
    

    可以使用 data.xml 文件来迁移新表中包含的数据。

    更新 2:

    也可以使用 groovy 生成 liquibase 变更集。

    import groovy.sql.Sql 
    import groovy.xml.MarkupBuilder
    
    //
    // DB connection
    //
    this.class.classLoader.rootLoader.addURL(new URL("file:///home/path/to/h2-1.3.162.jar"))
    def sql = Sql.newInstance("jdbc:h2:db/db1","user","pass","org.h2.Driver")
    
    //
    // Generate liquibase changeset
    //
    def author = "generated"
    def id = 1
    
    new File("extract.xml").withWriter { writer ->
        def xml = new MarkupBuilder(writer);
    
        xml.databaseChangeLog(
            "xmlns":"http://www.liquibase.org/xml/ns/dbchangelog",
            "xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance",
            "xsi:schemaLocation":"http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd"
        ) {
            changeSet(author:author, id:id++) {
                sql.eachRow("select * from employee") { row ->
                    insert(tableName:"exmployee") {
                        column(name:"empno",    valueNumeric:row.empno)
                        column(name:"name",     value:row.name)
                        column(name:"job",      value:row.job)
                        column(name:"hiredate", value:row.hiredate)
                        column(name:"salary",   valueNumeric:row.salary)
                    }
                }
            }
        }
    }
    

    【讨论】:

    • hiee 我可以看到差异,但是如果缺少表,它只会创建表,但不会将表数据从源数据库复制到目标数据库。有什么解决办法吗
    • 不,不是一个完整的解决方案。我已经更新了我的答案,以表明如何将数据转储为一系列变更集。此生成的数据可用于在新数据库中加载新表。
    • hiee 在执行命令后它给出了 java 堆空间错误。我尝试将 java 堆大小设置为 %JAVA_OPTS% -Xms512m -Xmx1024m -XX:MaxPermSize=1024m。你能帮我解决这个问题吗?
    • 我认为你的数据集太大了。尝试生成变更集(更新了我的答案)或者只是使用普通的数据库数据加载工具。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多