preconditions failure (<not><tableExists>)

hi

i am new to liquibase.

in the process of starting with liquibase, i created a baseline of our legacy db schema. updates are then made relative to this baseline.

i ran into errors when running the baseline + updates for the first time against an existing database consisting of just the baseline schema.

the baseline itself failed. this was due to tables already present.

i then updated the baseline to include preConditions, e.g.:

  
    
  

psql also confirms that the table exists:

\dt alarm
          List of relations
 Schema | Name  | Type  |   Owner
--------+-------+-------+------------
 public | alarm | table | myUser
(1 row)

when running this new update it failed again:

SEVERE: Preconditions Failed                                                                                                                         

liquibase.exception.MigrationFailedException: Migration failed for change set changelogs/r6.10/baseline.xml::1248689548526-1::naude_r (generated):                                                                                      
     Reason:                                                                                                                                         

          Not precondition failed                                                                                                                      
:                                                                                                                                                      
          Caused By: Preconditions Failed

this was unexpected…but maybe i just do not understand how preConditions are supposed to work.

i did take a look at the code, both NotPrecondition and TableExistsPrecondition.

if a table exists then TableExistsPrecondition will not raise an exception. NotPrecondition will then error out because it expects an exception!

i was hoping that the preConditions would follow some form of boolean evaluation, i.e. not(tableExists) = not(true) = false, thus the createTable would not execute.

does anyone have any idea on how to overcome the issue?

it may make things easier if all preConditions are evaluated using booleans, e.g.
public boolean check(Database database, DatabaseChangeLog changeLog) throws PreconditionFailedException, PreconditionErrorException;

NotPrecondition would then return !precondition.check(database, changeLog); Or and And would work in similar vain.

regards
roelof.

updating the preConditions from:

Originally posted by: roelof
  
    
  

to:

  
    
  

allowed things to work.

Glad you found the answer.  The idea of preconditions is to do a boolean check that the database is in a particular state before executing the changeset.  In your case, that a given table does not exist.  The onFail changes the behavior of what happens when the precondtion fails from “fail update” to “mark already ran”.

I’m sure you figured it out, I’m just adding some info in case others have the same problem.

Nathan

Same idea here, but it’s failing.  Here’s my migration:

   

       
           
               
           
       
       
       
   

It generates:

Migration Failed: Unknown Reason.  For more information, use the --logLevel flag)
Dec 10, 2009 3:27:00 PM liquibase.commandline.Main main
SEVERE: Unknown Reason
liquibase.exception.MigrationFailedException: Migration failed for change set baseline.xml::1::djantzen:
    Reason: java.lang.NullPointerException:
         Caused By: null
at liquibase.ChangeSet.execute(ChangeSet.java:260)
at liquibase.parser.visitor.UpdateVisitor.visit(UpdateVisitor.java:26)
at liquibase.parser.ChangeLogIterator.run(ChangeLogIterator.java:41)
at liquibase.Liquibase.update(Liquibase.java:165)
at liquibase.commandline.Main.doMigration(Main.java:660)
at liquibase.commandline.Main.main(Main.java:97)
Caused by: java.lang.NullPointerException
at liquibase.database.structure.SqlDatabaseSnapshot.readIndexes(SqlDatabaseSnapshot.java:505)
at liquibase.database.structure.SqlDatabaseSnapshot.(SqlDatabaseSnapshot.java:99)
at liquibase.database.structure.PostgresDatabaseSnapshot.(PostgresDatabaseSnapshot.java:35)
at liquibase.database.PostgresDatabase.createDatabaseSnapshot(PostgresDatabase.java:447)
at liquibase.preconditions.TableExistsPrecondition.check(TableExistsPrecondition.java:34)
at liquibase.preconditions.NotPrecondition.check(NotPrecondition.java:18)
at liquibase.preconditions.AndPrecondition.check(AndPrecondition.java:21)
at liquibase.ChangeSet.execute(ChangeSet.java:169)
… 5 more

This is liquibase 1.9.5.  Any idea what would cause this?
Thanks,
David

It looks like a problem with a unique constraint it is trying to read.  In the 1.9 codebase, db structure precondtions did a full database snapshot then read from that snapshot, and so even though you aren’t looking a the unique constraint it is still being diffed and there is some null data coming back about the table name and/or column names.  

Was there a unique constraint added lately that could be causing the problem?

What database are you using?

Nathan

Hi Nathan, thanks for the response.  The database is Postgres 8.3.  I’m trying to Liquibase-ify a preexisting database.  I have this baseline migration so the db can be created in dev/test environments, and then I’ve got a couple new migrations that add tables.  The only uniqueness constraints on the new tables are for primary keys.

It works in my dev environment with an empty database created from the baseline SQL (not a a generated Liquibase-changelog, maybe that matters).  Migrating an extant and populated test database is where I see this error.

Hi Nathan,

I’m seeing this on another database now.  I took a SQL schema dump from a live Postgres 8.3 and loaded it into a dev machine.  The first run was fine.  Then I deleted databasechangelog tables to emulate the production database and reran the baseline.  It explodes with hundreds of warnings like:

INFO: Could not find table or view pgstattuple_type for column dead_tuple_percent
Dec 22, 2009 1:40:05 PM liquibase.database.structure.SqlDatabaseSnapshot readColumns
INFO: Could not find table or view pgstattuple_type for column free_space
Dec 22, 2009 1:40:05 PM liquibase.database.structure.SqlDatabaseSnapshot readColumns

Then ends with the aforementioned NullPointer.

Any suggestions for a workaround here (besides commenting out the changeset)?  Seems very odd to me that a simple table existence check reads in the entire database structure (and blows up). 

We did a full database snapshot because that was the easiest to implement, given that we already had that functionality.  2.0 is now smart enough to just read the needed metadata, so one option would be to switch to liquibase 2.0 (http://liquibase.org/ci/latest).  It is not officially released, but it is very close.

It’s hard to track down what exactly is causing the problem without your database.  Have you tried it with 1.9.5 (the latest official release? ) Would you have the ability to download the source and step through the code to see what is generating the null pointer exception?  Do you have a test database you could send me (even directly to nathan[at]voxland.net) that I could use to replicate the problem?

Nathan

Sorry for the delayed response.  This problem is occurring with 1.9.5.  I’m trying to put together a test database that will show how to replicate the behavior, but it’s at the bottom of a long list of todos for me.  Is there a publicly accessible SVN repo for the core codebase?  All I could find was the CONTRIB module. 

The SVN repository for trunk is at http://liquibase.jira.com/svn/CORE/trunk.  A testcase would help a lot.

Nathan