问题
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.
回答1:
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
回答2:
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)
回答3:
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
回答4:
I solved this by running the dropwizard-migrations "fast-forward" command as follows:
java -jar hello-world.jar db fast-forward helloworld.yml
This will mark the next changeset as applied without actually applying it. You may have to do this one time per changeset you want to fast-forward. There is also an --all flag if you want to fast forward everything.
More details can be found here: http://dropwizard.codahale.com/manual/migrations/
来源:https://stackoverflow.com/questions/18796217/liquibase-preconditions-not-working