Reputation: 1447
I'm using Liquibase with Maven in a project - v4.2.0.
My changelogs are on the file system, rather than in the JAR or classpath of the project.
I'm using the following to establish my object:
liquibase = new Liquibase( changeLogFile, new FileSystemResourceAccessor(), database );
where the changelogFile
is something like ~/liquibase-sql/changelog/db.changelog.xml
When I call liquibase.validate()
, I get the following, after a reminder of the classpath locations:
Specifying files by absolute path was removed in Liquibase 4.0. Please use a relative path or add '/' to the classpath parameter.
I've tried various things including a file:
prefix, and the file is question can be opened in terminal directly.
I have looked through the code and I'm confused by the concept of FileSystemResourceAccessor
being named as such if it can only use the classpath (there's already a ClassLoaderResourceAccessor
), but I can't see a way to make it work.
Based on very very old questions people have managed this before, but I assume prior to 4.0? (this works fine on 3.10.3)
Does anyone have any pointers? I've used CLI liquibase and understand the error, but I'm not sure how I can not determine the path without it being absolute, on the understanding that this would be potentially be ran on a few different machines in arbitrary locations.
This might be niche question, but thanks for any help in advance.
Upvotes: 8
Views: 3932
Reputation: 6852
I am using liquibase 4.5.0 and the below thing worked for me.
val database =
DatabaseFactory.getInstance()
.findCorrectDatabaseImplementation(
new JdbcConnection(
DriverManager.getConnection(
jdbcUrl,
getPostgresContainerConfig().username(),
getPostgresContainerConfig().password())));
new liquibase.Liquibase(
"analytics/target/classes/create_db.sql",
new FileSystemResourceAccessor(
new File("/Users/debrajmanna/code/java/github/sp/src/java/")),
database);
My file was in /Users/debrajmanna/code/java/github/sp/src/java/analytics/target/classes/create_db.sql
Upvotes: 0
Reputation: 591
I would like to react to putting scripts outside of classpath/jar. I took a look around because we wanted to do this as well.
From my point of view, I would say it is not a good approach because anyone can go to the location of the scripts and touch these files which can cause Liquibase to fail. Except that you can go and put any script to that location and modify a database.
I think the authors of Liquibase know why there is no straightforward approach to how to do that.
Upvotes: 0
Reputation: 3915
Here is what I ended up doing (for a gradle-based project):
For gradle, this meant adding some stuff to build.gradle like so:
sourceSets {
test {
//whatever else you have
resources {
srcDir 'src/test/resources'
srcDir 'top-external-folder-of-changelog'
}
}
}
dependencies {
testImplementation files (path/to/external/folder)
}
The changelog schemaLocation attribute then looks like this:
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.11.xsd"
Remember to adjust for your version,
My specific issues was with tests. For real environments, the liquibase scripts are applied to the database via an external (liquibase-based) tool.
Upvotes: 3