【问题标题】:Liquibase preconditions not workingLiquibase 前提条件不起作用
【发布时间】:2013-09-13 22:31:15
【问题描述】:

我正在尝试使用 liquibase 通过 dropwizard-migrations 跟踪对 postgresql 数据库的更改。我希望能够在现有生产数据库上运行迁移,而不是从头开始重建。现在我正在分期进行测试。我创建了一个带有前提条件的变更集。

<changeSet id="3" author="me">
    <preConditions onFail="CONTINUE">
        <not>
            <sequenceExists sequenceName="emails_id_seq"/>
        </not>
    </preConditions>
    <createSequence sequenceName="emails_id_seq" startValue="1" incrementBy="1" />
</changeSet>

如果序列已经存在,我的目标是跳过应用变更集。看起来很简单,但它不起作用。

ERROR [2013-09-13 22:19:22,564] liquibase: Change Set migrations.xml::3::me failed.  Error: Error executing SQL CREATE SEQUENCE emails_id_seq START WITH 1 INCREMENT BY 1: ERROR: relation "emails_id_seq" already exists
! liquibase.exception.DatabaseException: Error executing SQL CREATE SEQUENCE emails_id_seq START WITH 1 INCREMENT BY 1: ERROR: relation "emails_id_seq" already exists

我也尝试过使用 MARK_RAN 而不是 CONTINUE。运气不好。

【问题讨论】:

    标签: postgresql liquibase


    【解决方案1】:

    将变更集应用到现有数据库而不执行的更简单的方法是使用changelogSync 命令。

    以下命令演示了如何提取变更日志,然后将其与当前数据库同步:

    liquibase --changeLogFile=mydb.xml generateChangeLog
    liquibase --changeLogFile=mydb.xml changelogSync
    

    sync 命令的作用是在 changelog 表中创建所有条目,以便现在可以正常使用 liquibase 文件来更新数据库:

    liquibase --changeLogFile=mydb.xml update
    

    【讨论】:

    • 我想使用 dropwizard 迁移模块来执行此操作。 dropwizard.codahale.com/manual/migrations
    • @AnnKilzer 我没有使用 dropwizard,但我的理解是它包装了 liquibase。在这种情况下,使用 liquibase 命令行运行 changelogsync 命令,这将使数据库中的 changelog 表保持最新。然后您就可以进行正常的迁移了。
    • 不幸的是,该命令不在 dropwizard 迁移 api 中:错误:无效选择:'changelogSync'(从 'calculate-checksum'、'clear-checksums'、'drop-all'、'dump 中选择) '、'fast-forward'、'generate-docs'、'locks'、'migrate'、'prepare-rollback'、'rollback'、'status'、'tag'、'test')
    • 看来我需要使用 dropwizard-migrations "fast-forward" 命令来更新现有数据库。感谢您的帮助:)
    【解决方案2】:

    我使用 sqlCheck 指令解决了这个问题:

    <changeSet id="sys-0" context="structural">
        <preConditions onFail="MARK_RAN"><sqlCheck expectedResult="0">SELECT count(c.relname) FROM pg_class c WHERE c.relkind = 'S' and c.relname = 'hibernate_sequence'</sqlCheck></preConditions>
    <!--        <preConditions><not><sequenceExists schemaName="public" sequenceName="hibernate_sequence"/></not></preConditions> -->
        <createSequence schemaName="public" sequenceName="hibernate_sequence"/>
    </changeSet>
    

    (在 liquibase 2.0.1 版本上测试)

    【讨论】:

      【解决方案3】:

      我对视图做了同样的事情,对我来说它有效:

      也许会给你一些想法:

      <changeSet author="e-ballo" id="DropViewsAndcreateSynonyms" context="dev,int,uat,prod">
          <preConditions onFail="CONTINUE" >
              <viewExists viewName="PMV_PACKAGE_ITEMS" schemaName="ZON"/>
              <viewExists viewName="PMV_SUBSPLAN_INSTALLTYPES" schemaName="ZON"/>
          </preConditions>
          <dropView schemaName="ZON" viewName="PMV_PACKAGE_ITEMS"  />
          <dropView schemaName="ZON" viewName="PMV_SUBSPLAN_INSTALLTYPES"  />
          <sqlFile path="environment-synonyms.sql" relativeToChangelogFile="true" splitStatements="true" stripComments="true"/>
      </changeSet>
      

      希望对你有帮助

      【讨论】:

      • 谢谢。需要将 schemaName 和 tableName 添加到我们的工作中。
      【解决方案4】:

      我通过运行 dropwizard-migrations "fast-forward" 命令解决了这个问题,如下所示:

      java -jar hello-world.jar db fast-forward helloworld.yml
      

      这会将下一个变更集标记为已应用,而不实际应用它。对于每个要快进的变更集,您可能必须执行一次。如果您想快进所有内容,还有一个 --all 标志。

      更多详情可以在这里找到:http://dropwizard.codahale.com/manual/migrations/

      【讨论】:

        猜你喜欢
        • 2021-10-08
        • 2017-01-02
        • 2015-08-15
        • 2017-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-01
        • 2020-07-04
        相关资源
        最近更新 更多