Search code examples
spring-bootliquibase

Liquibase parameter in sql file with spring-boot


In my changelog xml file I have the following

<?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="seed_testtest_18" author="me" failOnError="true">
        <sqlFile path="dml/seed-data.sql" relativeToChangelogFile="true" />
    </changeSet>


</databaseChangeLog>

In the dml/seed-data.sql file I need to use a variable based on spring boot profile that is being used

INSERT INTO ${keyspace}.TESTTEST (ID, NAME, AGE, EMAIL, PHONE) VALUES (14, 'Dennis Vo', 20, 'dennis.n.vo@chase.com', '272-324-8912');

in my application.yml file I have keyspace defined as below

spring:
  config:
    activate:
      on-profile: local

  liquibase:
    parameters:
      keyspace: localkeyspace

However the value of keyspace is not being used when I run the application. Is there anyway to do this when using a sql file?


Solution

  • As I understand, you want to use a different schema/keyspace (cassandra!?) in different environments!?

    Make your sql "schema/keyspace-free":

    INSERT INTO TESTTEST -- ...
    

    Then in application-local.properties, we would:

    spring.liquibase.defaultSchema=localkeyspace
    

    ...in application-int.properties:

    spring.liquibase.defaultSchema=int_keyspace
    

    ...in application[-prod].properties:

    spring.liquibase.defaultSchema=prod_keyspace
    

    This will (hopefully) route your(1) scripts to the correct schema per environment.


    If there is "more dynamics" in the sqls than this (built-in liquibase configuration), we must: maintain multiple sql's of the same changeset (-> contexts: https://docs.liquibase.com/workflows/liquibase-community/existing-project.html), and then can write:

    <changeSet id="seed_testtest_18_local" context="local" author="me" failOnError="true">
      <sqlFile path="dml/seed-data_local.sql" relativeToChangelogFile="true" />
    </changeSet>
    <changeSet id="seed_testtest_18_uat" context="uat" author="me" failOnError="true">
      <sqlFile path="dml/seed-data_uat.sql" relativeToChangelogFile="true" />
    </changeSet>
    <changeSet id="seed_testtest_18_prod" context="prod" author="me" failOnError="true">
      <sqlFile path="dml/seed-data_prod.sql" relativeToChangelogFile="true" />
    </changeSet>
    

    and in application[-profile].properties|yaml:

    spring.liquibase.contexts=local # ...or e.g.: !local, uat & prod, ${spring.profiles.active}..., matching changelog contexts!
    

    LiquibaseProperties


    Another (build-time) approach: maven profiles + resource filtering/antrun/...