Liquibase: How to disable FILENAME column check? - liquibase

For our application we use liquibase. We have a need to run DB migrations both from command line (manually on production) AND automatically as the application starts up (test environment etc).
The problem is that Liquibase considers the whole filename as a portion of a changeSet's identity, therefore it tries to reapply the changesets if the path is different. For example, in case of "fully qualified path" VS "relative path" to to the db-changelog file.
How to disable FILENAME column check?

Based on this, the approach is as follows:
Always use the logicalFilePath attribute on both the databaseChangeLog element and every changeSet element.
Example:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<databaseChangeLog logicalFilePath="does-not-matter" xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd">
<changeSet logicalFilePath="path-independent" author="authorId" id="1">
...
</changeSet>
</databaseChangeLog>
As result, FILENAME column for all changesets will contain 'path-independent' and check will be omitted.

#snowindy's answer is good. Alternately, you can always refer to your changeLogs in a classpath-relative manner such as com/example/changelog.xml. if you configure the classpath correctly in both environments the same "com/example/changelog.xml" can be used.

There's another factor that comes into play. There are different ways to reference the changeLogFile (absolute/relative path or by classpath). I wrote about it in detail here: https://stackoverflow.com/a/45644695/4176104

Related

How to put one or several package files into a changelog in sql format

in a changelogfile (in sql mode), I want to update or create severals package.
I don't want to write all the package in 1 file.
I want to be able to do a rollback.
How can I do it ?
the oracle command "#" is not recognized.
thanks
Michel
If I understand your question correctly, it is the Include tag you are looking for.
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet id="a_changeset" author="a_developer">
<comment>Doing some stuff</comment>
...
</changeSet>
<include file="someMoreChangeSets.xml" />
</xml?
I can't use your solution because I only use sql file (myfile.sql)
I think it's not the better solution to use sql files, but I don't want to totally change "How the developpers code"
thanks
Michel

How do I configure liquibase to use relative path for the filename column on table DATABASECHANGELOG?

I'm using liquibase version 3.4
After I execute a liquibase changeset, I see the following entry into the changelog
INSERT INTO DATABASECHANGELOG (ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, MD5SUM, DESCRIPTION, COMMENTS, EXECTYPE, CONTEXTS, LABELS, LIQUIBASE) VALUES ('1561715333', 'userx', 'C:/TeamCity.BuildAgent/work/CMSLiquibase/src/main/resources/releases/1/core/ddl/JIRA-1000-ADD_COLUMN.xml', SYSTIMESTAMP, 17, '7:762a7c8960445ef94da88c10a81acd79', 'addColumn', 'Adding column', 'EXECUTED', NULL, NULL, '3.4.0');
For filename, liquibase generates the full path "C:/TeamCity.BuildAgent/work/CMSLiquibase/src/main/resources/releases/1/core/ddl/JIRA-1000-ADD_COLUMN.xml" where as I want the relative path "src/main/resources/releases/1/core/ddl/JIRA-1000-ADD_COLUMN.xml"
The liquibase documentation says Filename should be "Path to the changelog. This may be an absolute path or a relative path depending on how the changelog was passed to Liquibase. For best results, it should be a relative path"
But I cannot find any code examples on where this has been configured.
Any idea where I can configure this?
You can use the attribute logicalFilePath in the <databaseChangeLog> tag:
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd"
logicalFilePath="my_changelog.xml"> <<<<HERE
....
</databaseChangeLog>
Unfortunately there is no global setting to do that. You need to take care to do that for every changelog file you have.
Caution
If you change that if you have already run your existing change logs, you need to change the values in the database! Liquibase detects a changeset with the combination of filename, author and id. So if you change the logicalFilePath for something that has already been run, Liquibase will think it's a new change log and will try to run all changesets in the file again.

Run SQL Files If Changed or Run New SQL Files in Folder with Liquibase

I have a sql folder and sql files in this folder.
I want to run every changes in this folder.
For example: if new sql file is added on sql folder, I want to run it or if new lines are added to one of the files in this folder, I want to run only new lines. Is there any possibility to make this with Liquibase ?
Here is my changelog xml.
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet id="1359722450-38" author="garip" runOnChange="true">
<sqlFile endDelimiter="" splitStatements="false" path="../sql/sql1.sql"
relativeToChangelogFile="true" />
</changeSet>
</databaseChangeLog>
The place where you will have problems is the request
...or if new lines are added to one of the files in this folder, I want
to run only new lines.
Liquibase will only run an entire SQL script. In order to just run the 'new' lines it would have to parse and understand all the different SQL dialects, which Liquibase does not do.
Try to combine Liquibase without changelogs (http://www.liquibase.org/2015/09/liquibase-without-changelogs.html) and runOnChange option (http://www.liquibase.org/documentation/changeset.html), but "if new lines are added to one of the files in this folder, I want to run only new lines" is not possible - you can run only the whole file if it is changed.

How include files in changeLog by mask

We have pretty standard change-log.xml:
<databaseChangeLog …>
<include file="changes/change1.xml"/>
<include file="changes/change2.xml"/>
…
<include file="changes/changeN.xml"/>
</databaseChangeLog>
The problem is N is constantly climbing and is already around 200, considering that we're only using liquibase for several months, I'm concerned that the file will soon become too big to work with comfortably. Also I don't like that several developers can change this file concurrently, yes Git takes care of conflicts, but still I don't like it. Another problem is that developers have to remember updating the file each time they write a new change file.
Is there a way to include files by mask? Something along the lines of
<databaseChangeLog …>
<include file="changes/*.xml"/>
</databaseChangeLog>
You can just specify the path in includeAll tag, we use it like this:
<includeAll path="config/liquibase/changelog/" relativeToChangelogFile="false"/>
In your case it may be
<includeAll path="changes/"/>

Liquibase runOnChange="true" but stored function in sqlFile not updated in database for changes

I have a changeset :
<?xml version="1.0" encoding="UTF-8" ?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd">
<changeSet id="1359722450-38" author="myname" runOnChange="true" >
<sqlFile endDelimiter="" splitStatements="false" path="sql/38_getLeadSet.sql" relativeToChangelogFile="true" />
<rollback>DROP FUNCTION `getLeadSet`</rollback>
</changeSet>
</databaseChangeLog>
which is included by a mater log files
I if change sth in sql/38_getLeadSet.sql and run liquibase update , I get :
FUNCTION getLeadSet already exists liquibase.exception.DatabaseException: Error executing SQL ... getLeadSet....
on command line. Seems to be same issue as mentions here ,but I have latest liquibase version
any kind of suggestion is appreciated , thanks
Edit
Well we need drop sql before the sql file tag e.g
<sql>DROP FUNCTION if exists `getLeadSet`</sql>
<sqlFile endDelimiter="" splitStatements="false" path="sql/38_getLeadSet.sql" relativeToChangelogFile="true" />
<rollback>DROP FUNCTION `getLeadSet`</rollback>
P.S) Liquibase Version: 2.0.5
runOnChange="true" is not working, instead I used runAlways="true" which is working.
I have decided to use runAlways="true" instead of runOnChange="true" in my project, because that doesn't make much difference for my project during the deployment.
liquibase version is 3.5.1
Are you rolling back your change before updating it again? Because the function getLeadSet would already be exisiting and you may be getting a sql error rather that a liquiabase one.