using Preconditions with multiple databaseChangeLogs

( ??? noob sorting things out…  ???)

In a table I have a value representing the current schema. This is so client applications can ensure they are running against the right schema.

As per the example, I have multiple files each with a specific set of changes:
<databaseChangeLog …>
 
 

 
 

Each set is essentially a migration script from Schema X to Schema X+1. Each databaseChangeLog (in the individual files) has a check to ensure the database is the appropriate schema, and if so, it will pass, and the remainder of the changeSet will run:

<databaseChangeLog …>

 
   
      SELECT [Value] FROM [SYSTEM].[Parameter] WHERE [ParameterName]=‘SchemaVersion’
   
 

… changes to get to schema 2 …

Then the last thing the databaseChangeLog does is update the SchemaVersion to the appropriate value.

Now I also have external clients with databases at a particular schema version in the middle, and the migration should be able to handle all previous versions. When I run the migration, it should only run the migration scripts to get up to the latest version (in the above example version 7), regardless of where it started at.

What’s the best why of achieving this? On the databaseChangeLog PreConditions I want to use onFail=“CONTINUE” or “MARK_RAN”, but they’re not options at that level.

Any other ideas?

Thanks in advance.

Phil

I think you could get by fine without the check and it will do exactly what you want.  Liquibase tracks each changeSet to know whether it should be ran or not and doesn’t need an extra precondition.  That example was some contributed documentation, and now that I think through it I think that check will just confuse and possibly cause problems like you mention.  I’ll pull it out.

Nathan

I’m not sure it will operate as I want it to. Let me give you an example.

For sake of the example, we’ll say that the current schema version is 7.

An old client is currently at schema version 4 (v4).  Installed is the key here - it went straight to schema 3, without any migrations from schema 1 or 2. So, there is nothing DATABASECHANGELOG - Liquibase has no idea what changeSets have been run. If I try to run all the changeSet (including those to migrate from v1 to v2 to v3 to v4), I would expect refactorings to fail all over the place, because the database is not at the expected state.  For example, columns that a changeSet wants to add in are already there.

So, I want liquiBase to detect that the database is at v4, and only run the changeSets to get to v7.

One way I’ve thought of is to put the precondition check in each changeSet, but that does seem like overkill, and prone to Human Error when writing the changeSet. I’d much prefer to be able to write it once for each update script.

Thanks for your help…

How did they get installed at that version?  A backup/restore or some other way?

If it is a restore, if you restore the databasechangelog table liquibase will still think the changesets have ran.

If you are installing the database differently, is there another way to initialize the databaschangelog table?

Nathan

The initial database schemas are created from a script file. Usually what we’ve done is hand crafted the update scripts, which is what we want to replace by using Liquibase.

So, there’s no real reason or desire to want to create /  insert / update the DATABASECHANGELOGxxx tables.

At the moment, I’m testing putting the check into each change, rather than each file. At least then I can ensure that Liquibase will only do what is required, and log it as such.

Can you think of any other way of doing this?

(Thanks again for you help. Despite this issue, Liquibase is a great step forward!!)

Phil

I think having the checks on each changeSet is the only way you can go at this point, besides gettign into the liquibase code adding support for MARK_RAN ont he changeSet wide preconditions and contributing a patch :) 

I would suggest getting the databasechangelog populated, even with “ran” changesets. That makes less work for you and lets you better leverate the changeSEt tracking built into liquibase.  There is a “changelogSync” and “changelogSyncSQL” command that will update/generate SQL to mark all changesets as ran.  You could run that for each schema version, then tack the changeLogSync SQL onto the end of your install process and as far as liquibase cares, all the earlier changeSets were ran.

Nathan

Hello!

I revive this topic as I found the first proposal interesting in that it is simple to check and prevent changelogs to be applied.

I would try that bit of code (even if I know it is not correct)

                            SELECT IFNULL(MAX(id),0)             FROM DATABASECHANGELOG             WHERE author='MajorVersion'                

It would be very pleasant to get this working, don’t you think?
I prefer this solution compared to the databasechangelog populated manually…

Regards,