Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Liquibase preconditions not working

I'm trying to use liquibase to track changes to a postgresql database using dropwizard-migrations. I'd like to be able to run the migration on the existing production database instead of rebuilding from scratch. Right now I'm testing in staging. I've created a changeset with a precondition.

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

My goal is to skip applying the changeset if the sequence is already there. Seems straightforward, but it's not working.

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

I've tried using the MARK_RAN instead of CONTINUE too. No luck with that.

like image 210
Ann Kilzer Avatar asked Sep 13 '13 22:09

Ann Kilzer


3 Answers

A much simpler way to apply your changesets to an existing database, without execution, is to use the changelogSync command.

The following commands demonstrate how to extract a changelog and then sync it with the current database:

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

What the sync command does is create all the entries in the changelog table, so that the liquibase file can now be used as normal to update the database:

liquibase --changeLogFile=mydb.xml update
like image 98
Mark O'Connor Avatar answered Nov 15 '22 04:11

Mark O'Connor


I solved this problem using the sqlCheck instruction :

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

(tested on liquibase 2.0.1 version)

like image 39
christouilhe Avatar answered Nov 15 '22 05:11

christouilhe


I did the same that you want to do with a view, and for me it works:

Maybe gives you some idea:

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

I hope it helps

like image 38
eballo Avatar answered Nov 15 '22 04:11

eballo