Liquibase not executing changeset on H2 DB when precondition exists (tableexists) - h2

In first change set table tb_transformation is already created. Below is the 4th changeset where i insert extra column to table when precondition passes. But its not executing the changeset. When i remove precondition and execute its inserting successfully.
<changeSet id="2020-03-004-add-columns-to-tb_transformation" author="TAAS">
<preConditions onFail="CONTINUE">
<tableExists tableName="TB_TRANSFORMATION"/>
</preConditions>
<addColumn tableName="TB_TRANSFORMATION">
<column name="MARKET_INFRASTRUCTURE" type="varchar(255)">
<constraints nullable="false"/>
</column>
</addColumn>

Are there some environments where the table might not exist? If not, and everything is being 'controlled' by Liquibase, then you should just be able to remove the precondition.

Related

How to update tables in multiple schema in a database with a single changeset using liquibase for a multi-tenant application

I have a database with multiple schemas with same tables.
Inorder to update a particular schema "tenant1" below syntax can be used
<changeSet id="1660156908997-1" author="manu">
<addColumn schemaName="tenant1" tableName="question">
<column name="weightage" type="INT">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>
Inorder to update two schemas viz., "tenant1" and "tenant2", below command can be used,
<changeSet id="1660156908997-1" author="manu">
<addColumn schemaName="tenant1" tableName="question">
<column name="weightage" type="INT">
<constraints nullable="false"/>
</column>
</addColumn>
<addColumn schemaName="tenant2" tableName="question">
<column name="weightage" type="INT">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet
But can we automate this and update all schemas with a single entry inside changeset?
Do you know about changelog parameters?
What I would do is to parameterise the changes and then for each of your tenant definitions in your application execute the same changelog but with different parameters.
ChangeLog could look like this:
<changeSet id="1660156908997-1-${tenant}" author="manu">
<addColumn schemaName="${tenant}" tableName="question">
<column name="weightage" type="INT">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>

Springboot Liquibase AWS Aurora DB Application Startup issue

I have an existing spring boot application and i need to connect to Aurora DB using liquibase and create tables . I have added all the required steps as below but when application is getting deployed not seeing any logs specific to liquibase and the changeSet are not getting executed . Please help do debug the issue .
1.db.changelog-master.xml (created under resources/db/changelog )
<preConditions>
<not>
<tableExists tableName="table1"/>
</not>
</preConditions>
<changeSet id="1" author="name">
<createTable tableName="category">
<column name="id" type="int" autoIncrement="true">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="name" type="varchar(250)">
<constraints unique="true" nullable="false"/>
</column>
</createTable>
</changeSet>
</databaseChangeLog>
application.properties
#Liquibase configuration
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://aws-aurora-conn-url:3306/database-name
spring.datasource.username=usename
spring.datasource.password=password
spring.liquibase.change-log=classpath:db/changelog/db.changelog-master.xml
spring.liquibase.enabled=true
build.gradle added these dependencies
implementation 'org.liquibase:liquibase-core'
implementation 'mysql:mysql-connector-java'
Thanks in advance
Issue was due to precondition check failure. Added the condition check in db.changelog-master.xml and was able to connect it . this will not fail the application instance instead its logs it and proceed
<preConditions onFail="WARN">
<not>
<tableExists tableName="table1"/>
</not>

how set failOnError=“false” in Liquibase maven?

how can i set failOnError=“false” for all changeSet when generate changeLog with maven Liquibase:Diff
<changeSet author="aliakbarazizkhani (generated)" id="1468579261546-1" failOnError="false">
<addColumn tableName="core_feedback">
<column name="solveuser" type="bytea"/>
</addColumn>
</changeSet>
This is not an option you can set on the command line. You would need to manually edit the changelog after it was generated to add the failOnError attribute to the appropriate change sets. It would be inadvisiable to apply that to all generated change sets.

Liquibase not picking up seed data with Spring Boot

I am using Spring-Boot 1.2.1, and Liquibase to create both H2 (testing) and PostgreSQL (QA & Production) databases. I have a couple of tables that I want to seed when the db is created. However, despite trying both dataLoad and sqlFile, nothing is getting inserted. My sql file is just a bunch of insert statements such as:
INSERT INTO state (Name, Code) VALUES('Alabama','AL');
INSERT INTO state (Name, Code) VALUES('Alaska','AK');
Here is my relevant changelog-master.xml:
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.3.xsd"
objectQuotingStrategy="QUOTE_ONLY_RESERVED_WORDS">
...
<changeSet id="3" author="me">
<createTable tableName="STATE">
<column name="code" type="VARCHAR(10)">
<constraints primaryKey="true"/>
</column>
<column name="name" type="VARCHAR(100)"/>
</createTable>
<sqlFile dbms="h2, PostgreSQL"
encoding="utf8"
endDelimiter="\nGO"
path="src/main/resources/db/changelog/data/states.sql"
relativeToChangelogFile="true"
splitStatements="true"
stripComments="true"/>
</changeSet>
Here is my project structure:
When I startup my spring-boot app, I can see that the State table is created, but it has zero rows in it. I also tried taking the out of changeset 3 and using this:
<changeSet id="4" author="me">
<loadData file="data/state.csv" tablename="STATE" schemaName="edentalmanager" relativeToChangelogFile="true">
<column name="name" type="VARCHAR(100)"/>
<column name="code" type="VARCHAR(10)"/>
</loadData>
</changeSet>
The csv file is basically:
Alabama,AL
Alaska,AK
...
I dont' see any messages in the console logs that Liquibase is trying to create or insert the data into the table. Nor do I get any exceptions or error messages.
UPDATE:
If I copy off the state.sql as /resources/data.sql then spring-boot picks up the file and executes the sql just fine. Unfortunately, this means every time I startup, it will try and insert those values again, causing startup exceptions (duplicate key violations) But, rather than rely on a single file, I would prefer Liquibase to execute them as part of the changeset as data needs change.
I think there are two issues in your changeset 3:
The value of the path property directs to a not existing resource. When you define relativeToChangelogFile="true" then Liquibase will look for classpath:/db/changelog/src/main/resources/.../states.sql. The correct path should be path="../data/states.sql".
If the given path is not correct Liquibase should throw an exception. If you didn't get one means Liquibase decided to not execute that part because of other conditions. One of those conditions could be the dbms property. Your changeset should work with a H2 database. It should not work with a PostgreSQL database because of a wrong type name. Try dbms="h2, postgresql" instead.
After those changes I got a filled table based on your project structure.
This is because by default Hibernate drops the schema when initializing. So first Liquibase creates the data and when finished Hibernate drops the tables and recreates them according to the JPA entities you defined.
You can verify this by looking for the log record:
2017-01-19 11:03:48.692 INFO 15161 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000227: Running hbm2ddl schema export
You can tell Hibernate not to do anything with the DB schema by setting this application property:
spring.jpa.hibernate.ddl-auto=none
I ran into this when upgrading to spring boot 2.4.1 from 2.2.0-RELEASE version. The 2.2.0-RELEASE version had liquibase-core:jar:3.8.0 as dependency and it was accurately taking relativeToChangelogFile="true". However the 2.4.1 version has liquibase-core:jar:3.10.3 version which breaks the loadData feature.
The csv file I was loading and the changelog.xml file were in the same class directory in my case src/main/resources/liquibase/version2/changelog.xml and src/main/resources/liquibase/version2/xref_specialty_codes.csv
Here is the snippet from my changelog.xml for loading the data which did not work with the later version of liquibase
<changeSet author="anon"
id="xref_specialty_codes_load_data"
objectQuotingStrategy="LEGACY">
<loadData catalogName="adb"
schemaName="public"
encoding="UTF-8"
file="xref_specialty_codes.csv"
relativeToChangelogFile="true"
separator=","
tableName="xref_specialty_codes"
usePreparedStatements="true">
<column name="id" type="NUMERIC"/>
...
....
</loadData>
</changeSet>
I load a hierarchy of change log files with the top one at src/main/resources/liquibase/changelog.xml with the following layout.
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<property name="now" value="now()" dbms="postgresql"/>
<include file="src/main/resources/liquibase/version1/changelog.xml" />
<include file="src/main/resources/liquibase/version2/changelog.xml" />
....
</databaseChangeLog>

Hsqldb has no data when populated via maven liquibase plugin

I've created schema and populated it via Maven liquibase plugin:
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>2.0.5</version>
<configuration>
<propertyFile>src/main/resources/db/config/db.config.properties</propertyFile>
<changeLogFile>src/main/resources/db/changelog/db.changelog-master.xml</changeLogFile>
</configuration>
</plugin>
Properties file:
driver: org.hsqldb.jdbcDriver
#HSQLDB Embedded in file
url: jdbc:hsqldb:file:src/main/resources/db/hsqldb/dataFile
username: SA
password:
As I see in the output when invoke mvn liquibase:update:
[INFO] Executing on Database: jdbc:hsqldb:file:src/main/resources/db/hsqldb/dataFile
INFO 24.04.13 10:00:liquibase: Successfully acquired change log lock
INFO 24.04.13 10:00:liquibase: Creating database history table with name: DATABASECHANGELOG
INFO 24.04.13 10:00:liquibase: Reading from DATABASECHANGELOG
INFO 24.04.13 10:00:liquibase: Reading from DATABASECHANGELOG
INFO 24.04.13 10:00:liquibase: ChangeSet src/main/resources/db/changelog/db.changelog-1.0.xml::1::sav ran successfully in 7ms
INFO 24.04.13 10:00:liquibase: ChangeSet src/main/resources/db/changelog/db.changelog-1.0.xml::2::sav ran successfully in 3ms
INFO 24.04.13 10:00:liquibase: Successfully released change log lock
INFO 24.04.13 10:00:liquibase: Successfully released change log lock
db.changelog-master.xml contains:
<include file="src/main/resources/db/changelog/db.changelog-1.0.xml"/>
db.changelog-1.0.xml contains:
<changeSet id="1" author="sav">
<createTable tableName="testTable">
<column name="id" type="int">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="name" type="varchar(50)">
<constraints nullable="false"/>
</column>
<column name="active" type="boolean" defaultValueBoolean="true"/>
</createTable>
</changeSet>
<changeSet id="2" author="sav">
<insert tableName="testTable">
<column name="id" value="1"/>
<column name="name" value="First String"/>
</insert>
<insert tableName="testTable">
<column name="id" value="2"/>
<column name="name" value="Second String"/>
<column name="active" value="false"/>
</insert>
</changeSet>
It seems everything is OK. Now i'm going to src/main/resources/db/hsqldb/ folder and see three files:
dataFile.log
dataFile.properties
dataFile.script
But I don't see a CREATE TABLE testTable DDL statement in the dataFile.script.
Next in Intelli IDEA I configure datasource plugin (set jdbc hsql driver, url: jdbc:hsqldb:file:/src/main/resources/db/hsqldb/dataFile, user: sa ). Connect it, invoke query:
SELECT * FROM INFORMATION_SCHEMA.SYSTEM_TABLES;
I cannot see the table I try to create.
The value of hsqldb_type field for each table - is MEMORY. I expect it to be FILE of something similar.
Any ideas?:)
PS:
1. Maven repository returns HSQLDB as the first search result, and its last version is 1.8.0.10. Actually I had to use HSQLDB DATABASE with its 2.2.9 version. It solved the problem of table creation.
2. I had to use an absolute path to the file AND the ';ifexists=true' property to connect to the existing database in IDEA datasource plugin. As a result my url connection string in the property file differ from the same used in the plugin.
You need to be careful about the use of file paths:
This is a relative path:
driver: org.hsqldb.jdbcDriver
#HSQLDB Embedded in file
url: jdbc:hsqldb:file:src/main/resources/db/hsqldb/dataFile
This is an absolute path within the current drive:
Next in Intelli IDEA I configure datasource plugin (set jdbc hsql driver, url: jdbc:hsqldb:file:/src/main/resources/db/hsqldb/dataFile, user: sa )
Try using absolute paths.
Apart from that, in your attempt to check things in an existing database, connect explicitly requiring the database to exist by adding ;ifexists=true to the connection URL.
As we are not sure Liquibase shuts down the database correctly or not, you can add a property to the Liquibase connection URL to ensure data is written fully ;hsqldb.write_delay=false. We are assuming you are using HSQLDB 2.x for this property.
With HSQLDB 1.8.x, liquibase <= 3.2.0 never read tables on database.
This is because catalog should be set null when retrieve JDBC metadata.
We could not force the catalog to be null, because the method AbstractJdbcDatabase.correctSchema() should not set catalog=schema, if supportCatalogs() return false.
I will post a issue for this.

Resources