I'm using org.postgresql:postgresql:42.1.4
with an instance of the official Postgres Docker image running via docker-compose
.
The database has the public
schema by default, and I manually create schemas; 001
and 002
each for a separate tenant.
The problem is that on application start-up, Liquibase executes the changelogs against public
.
How I can get Liquibase to only execute the changelogs against the 2 configured schemas? i.e 001
and 002
My Liquibase configuration to run migration changelogs on application start-up:
@Configuration
@EnableConfigurationProperties({LiquibaseProperties.class})
public class LiquibaseConfiguration {
private final Logger log = LoggerFactory.getLogger(LiquibaseConfiguration.class);
private final Environment env;
public LiquibaseConfiguration(Environment env) {
this.env = env;
}
@Bean
public SpringLiquibase liquibase(@Qualifier("taskExecutor") TaskExecutor taskExecutor,
DataSource dataSource, LiquibaseProperties liquibaseProperties) {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(dataSource);
liquibase.setChangeLog("config/liquibase/changelog/changelog-root.xml");
return liquibase;
}
@Bean
@DependsOn("liquibase") // ensure execution after SpringLiquibase Bean
public MultiTenantSpringLiquibase liquibaseMt(DataSource dataSource, LiquibaseProperties liquibaseProperties) {
MultiTenantSpringLiquibase liquibase = new MultiTenantSpringLiquibase();
liquibase.setDataSource(dataSource);
liquibase.setChangeLog("config/liquibase/changelog/changelog-root.xml");
liquibase.setSchemas(Arrays.asList("001", "002"));
return liquibase;
}
}
And a default DataSource
:
@Configuration
public class DataSourceConfig {
@Bean
public DataSource getDataSource() {
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("org.postgresql.Driver");
dataSourceBuilder.url("jdbc:postgresql://localhost:5432/postgres");
dataSourceBuilder.username("postgres");
dataSourceBuilder.password("");
return dataSourceBuilder.build();
}
}
The problem you have is the fact that SpringLiquibase
will by default auto run the changelog on the configured datasource, and for Postgres if no schema is specified the SQL scripts will be executed on the public
aka default schema. So you have two choices to do to stop liquibase from auto-executing against the default schema.
Just disable the autorun on SpringLiquibase
. There is a specific configuration property which can be used to disable/enable the autorun functionality. The property name is shouldRun
. So just set the value to false and the changelog will not be executed against the default schema.
@Bean
public SpringLiquibase liquibase(@Qualifier("taskExecutor") TaskExecutor taskExecutor,
DataSource dataSource, LiquibaseProperties liquibaseProperties) {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(dataSource);
liquibase.setChangeLog("config/liquibase/changelog/changelog-root.xml");
// here we tell the system not to run by default
liquibase.setShouldRun(false);
return liquibase;
}
You can totally disable default functionality for spring liquibase by excluding the LiquibaseAutoConfiguration
and just creating the MultiTenantSpringLiquibase
bean and delete the SpringLiquibase
bean creation.
To disable spring liquibase auto-configuration exclude the LiquibaseAutoConfiguration
@SpringBootApplication(exclude={LiquibaseAutoConfiguration.class})
Delete the creation of SpringLiquibase
bean.
@Configuration
@EnableConfigurationProperties({LiquibaseProperties.class})
public class LiquibaseConfiguration {
@Bean
public MultiTenantSpringLiquibase liquibaseMt(DataSource dataSource, LiquibaseProperties liquibaseProperties) {
MultiTenantSpringLiquibase liquibase = new MultiTenantSpringLiquibase();
liquibase.setDataSource(dataSource);
liquibase.setChangeLog("config/liquibase/changelog/changelog-root.xml");
liquibase.setSchemas(Arrays.asList("001", "002"));
return liquibase;
}
}