Liquibase sql generated error with column comments? - liquibase

When I add a new column comment , liquibase give me an error sql. How can I fix it ?
xml like :
<databaseChangeLog xxxxxxxx>
<changeSet author="root (generated)" id="1574189348049-1">
<setColumnRemarks columnName="nickname" remarks="nickname" tableName="t_user"/>
</changeSet>
</databaseChangeLog>
sql like :
ALTER TABLE testdb.t_user COMMENT = 'nickname';

Related

Two conditions in where tag of Liquibase

I want to add two conditions in where tag of liquibase and exception is thrown:
Reason: liquibase.exception.DatabaseException: Unknown column 'uid' in 'where clause' [Failed SQL: UPDATE kw.media_file SET created = '1586352959' WHERE id=1 AND uid='admin']
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
Here is the changeLog:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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"
logicalFilePath="src/main/resources/db/update.xml">
<changeSet author="author" id="20200409-update">
<update tableName="media_file">
<column name="last_modified" type="int(11)" value="1586438425"/>
<where>id=1 AND uid='admin'</where>
</update>
</changeSet>
Equivalent sql statement is here:
update person set created = 1586352959 where id = 2 and uid='admin';
When I run the SQL statement, the column is updated but no luck with liquibase.
As stated in the comment - the error and the changeSet you've provided don't match each other.
The error is that column uid is not found in table media_file
Your changeSet is synthetically correct, and you can provide multiple conditions in one <where> tag.
Based on the SQL statement you've provided
update person set created = 1586352959 where id = 2 and uid='admin';
So I can assume the changeSet you're looking for may look something like:
<changeSet author="foo" id="bar">
<update tableName="person">
<column name="created" type="int(11)" value="1586438425"/>
<where>id = 2 AND uid = 'admin'</where>
</update>
</changeSet>

How to add condition to changeSet

I created database ChangeLog for liquibase and I have "CREATE TABLE" query.
I want to add condition to column "STATUS".
<?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">
<changeSet id="1" author="xxx">
<comment>Create Asset table</comment>
<sql>
CREATE TABLE `TASK`(
`TASK_ID` bigint(20) NOT NULL,
`STATUS` VARCHAR(10), //(where status not equal to "pending")
`FILE_ID` varchar(100),
PRIMARY KEY (`DOC_ID`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
</sql>
</changeSet>
</databaseChangeLog>
If you want to update the columns datatype depending on certain conditions, you can use <preConditions> with <sqlCheck>, and then use <modifyDataType>.
So supposing that there's already a table with name TASK and it contains a column named STATUS, you can modify it's datatype as such:
<changeSet id="1" author="xxx">
<comment>Update Asset table</comment>
<preConditions onFail="MARK_RAN">
<and>
<columnExists tableName="TASK" columnName="STATUS"/>
<sqlCheck expectedResult="0"> SELECT COUNT(*) FROM TASK WHERE STATUS = "pending";</sqlCheck>
</and>
</preConditions>
<modifyDataType tableName="TASK" columnName="STATUS" newDataType="VARCHAR(10)"/>
</changeSet>
Or perhaps you'd like another onFail-behaviour. Check out this link
HALT - Immediately halt execution of entire change log [default]
CONTINUE - Skip over change set. Execution of change set will be
attempted again on the next update. Continue with change log.
MARK_RAN - Skip over change set, but mark it as ran. Continue with
change log
WARN - Output warning and continue executing change set as normal.

Set max column value as sequence start value with liquibase tags

I wonder if it possible to get maximum column value from a certain table and set it as start sequence value with no pure sql. The following code doesn't work:
<property name="maxId" value="(select max(id)+1 from some_table)" dbms="h2,mysql,postgres"/>
<changeSet author="author (generated)" id="1447943899053-1">
<createSequence sequenceName="id_seq" startValue="${maxId}" incrementBy="1"/>
</changeSet>
Got an error:
Caused by: liquibase.parser.core.ParsedNodeException: java.lang.NumberFormatException: For input string: "${m"
I've tried it with no parentheses around select ... etc. with the same result.
So it's not possible to use computed value as start sequence value?
So, such a solution worked for me:
<changeSet author="dfche" id="1448634241199-1">
<createSequence sequenceName="user_id_seq" startValue="1" incrementBy="1"/>
</changeSet>
<changeSet author="dfche" id="1448634241199-2">
<sql dbms="postgresql">select setval('user_id_seq', max(id)+1) from jhi_user</sql>
<sql dbms="h2">alter sequence user_id_seq restart with (select max(id)+1 from jhi_user)</sql>
</changeSet>
For postgres correct sql dbms sentence is:
<sql dbms="postgresql">select setval('some_table_id_seq', (select max(id)+1 from some_table), false)</sql>

Does LiquiBase generate invalid SQL?

For my MySql database I have a LiquiBase changeset that looks like this:
<changeSet id="ddl update tables : modify datatype for MY_TABLE.STATE_ABBREV" author="xxx">
<preConditions onFail="MARK_RAN" onFailMessage="Column MY_TABLE.STATE_ABBREV doesn't exists.">
<and>
<tableExists tableName="MY_TABLE"/>
<columnExists tableName="MY_TABLE" columnName="STATE_ABBREV"/>
</and>
</preConditions>
<update tableName="MY_TABLE">
<column name="STATE_ABBREV" value="AS"/>
<where>AGU
</where>
</update>
</changeSet>
This will result in
UPDATE MY_TABLE SET STATE_ABBREV = 'AS' WHERE AGU;
This does not look like valid ANSI SQL. Is this a LiquiBase bug or does LiquiBase do anything with this SQL before submitting to the database?
How can I tell LiquiBase to generate well-formed ANSI SQL?

Update type of a column in liquibase

I want to update the type of a column named "password". At the moment it has type NVARCHAR(40) and I want it to be of type NVARCHAR(64). This is what I did:
<changeSet id="1 - change password length" author="chris311">
<update tableName="tablename">
<column name="password" type="NVARCHAR(64)"/>
</update>
</changeSet>
What else is there to do? Because this obviously does not change anything in the DB.
You're using the wrong refactoring operation. Try modifyDataType
<changeSet id="increase-password-length" author="martin">
<modifyDataType tableName="tablename" columnName="password" newDataType="NVARCHAR(64)"/>
</changeSet>
You can check out http://www.liquibase.org/documentation/changes/modify_data_type.html for more documentation
Or you can do by using sql tag:
<changeSet author="liquibase-sql" id="example-sql" context="migrate">
<sql dbms="mysql">
ALTER TABLE tablename MODIFY COLUMN password NVARCHAR(64)
</sql>
</changeSet>