How to remove column attribute by liquibase? - liquibase

I have a column attribute
on update CURRENT_TIMESTAMP
How can I remove it in xml changeset ? Database is mysql.

If a refactor operation doesn't exist you can always fall back to a sql
<changeSet author="me" id="example-001">
<sql dbms="mysql">ALTER TABLE xxx MODIFY COLUMN yyy ????</sql>
</changeSet>

<changeSet id="someId" author="someAuthor" context="someContext">
<dropColumn tableName="tableName" columnName="columnNameToRemove" />
</changeSet>

Related

How to copy the the data from one Table to another Table Using Liquibase scripts

I want to know the solution for the below Test ( to copy the the data from one Table to another Table) using Liquibase a part of Corda.
Case: As part of I want to create a new table into an existing database which has already a table called TableA (which has id, name, value columns) which has some data init, I have created a TableB (which has same id, name, value columns) and I wanted to copy the data from TableA to TableB.
For that I had used the following liquibase script as suggested here in Liquibase and In-order to test I had connected to PostgreSQL DB and connected schema called "corda_schema" which has the tables.
<changeSet author="liquibase.corda" id="update-table">
<update schemaName="corda_schema" tableName="TableB">
<column name="id" valueComputed="(SELECT id from TableA)"/>
<column name="name" valueComputed="(SELECT name from TableA)"/>
<column name="value" valueComputed="(SELECT value from TableA)"/>
</update>
</changeSet>
I was getting the following error when I tried with the Liquibase update script
Error: liquibase.corda failed
Error: schema "CORDA_SCHEMA" not found in SQL statement
If I don't given the schema name in update like this
<update tableName="TableB">
<column name="value" valueComputed="(SELECT value from TableA)"/>
</update>
the Liquibase is searching in the Public schema for TableA and I get this error:
Error: liquibase.corda failed Error: schema "PUBLIC" not found in SQL statement`
And also I tried this Liquibase script changeSet by creating the table itself I tried to update data, this changeSet is running and table is created but data is not copied.
<changeSet author="liquibase.corda" id="update-table">
<createTable schemaName = "corda_schema" tableName="TableB">
<column name="id" valueComputed= "(SELECT id FROM TableA)"/>
</createTable>
</changeSet>
Please suggest anything I am missing or any other usages that will make my test success to get the data from one table to another table.
Thanks in advance.
I would suggest to just use custom sql:
<changeSet author="liquibase.corda" id="insert-table">
<sql>
insert into corda_schema.TableB
select id,name,value from corda_schema.TableA;
</sql>
</changeSet>

How to reference the default schema in liquibase preCondition sqlCheck

Posting here in case it helps someone.
TLDR: ${database.defaultSchemaName} within sqlCheck to access default schema name
I wanted my database changeset to first check if a certain row is present in the database. If not present, it should execute the changeset.
Example:
myschema.customers:
uuid
name
age
0001
Bob
22
0002
Sally
25
What I want: liquibase to check if uuid = 0002 is present in the myschema.customers table. If so, run the changeset, otherwise skip over it.
Initially I tried this:
<changeSet id="00000000000007" author="jhipster">
<preConditions onFail="MARK_RAN">
<sqlCheck expectedResult="0">
select count(*) from customers WHERE uuid= '0002'
</sqlCheck>
</preConditions>
<insert tableName="customers">
<column name="uuid" value="0002"></column>
<column name="name" value="Sally"></column>
<column name="age" value="25"></column>
</insert>
</changeSet>
Bear in mind that I have set the following configuration for liquibase (4.6.1)
spring:
liquibase:
default-schema: myschema
But it seems precondition sqlcheck was checking public.customers and not myschema.customers. This would cause an error when uuid 0002 is already present in myschema.customers.
SOLUTION: use ${database.defaultSchemaName}
<preConditions onFail="MARK_RAN">
<sqlCheck expectedResult="0">
select count(*) from ${database.defaultSchemaName}.customers WHERE uuid= '0002'
</sqlCheck>
</preConditions>

LiquiBase changeset: how do build a where clause based on ANOTHER table's column

Building upon the question How to build a WHERE-clause in a LiquiBase changeset, I would like to choose the default value of a column based on the value of a column from a different table.
For instance, I have two tables, order and order_history. Pls note that we maintain all our orders in both order in order_history as well. Once an order is completed, it is removed from order table.
order has a column 'status' but we missed it on order_history, you can call it a bad design.
How do I add 'status' to order_history now, and copy the value from the corresponding order
in order table for existing data at the time of upgrade? Is there a way to do this in liquibase?
If order and order_history are connected with the foreign key, then you can just do the following:
<changeSet id="foo" author="bar">
<preConditions onFail="MARK_RAN">
<and>
<columnExists tableName="order" columnName="status"/>
<columnExists tableName="order_history" columnName="status"/>
</and>
</preConditions>
<comment>Update order_history.status with values from order.status, where order.id = order_history.order_id</comment>
<update tableName="order_history">
<column name="status" valueComputed="SELECT o.status FROM order o WHERE o.id = order_id"/>
</update>
</changeSet>
If these tables are not connected, then you may use defaultValueComputed when you're adding a new column:
<addColumn tableName="order_history">
<column name="status" type="varchar(255)" defaultValueComputed="some SQL query here"/>
</addColumn>

How add specific type column by liqiubase

Postgresql has type INTERVAL for column. But I didn`t found simple way to create table with such column.
I have solution with two steps:
1. Create table by liquibase changeSet.
2. Use changeSet with sqlFile. Sql file contain sql for add column.
Example changeSet:
<changeSet author="author" id="add-testmy-table-v1">
<preConditions onFail="MARK_RAN">
<not>
<tableExists tableName="testmy"/>
</not>
</preConditions>
<createTable tableName="testmy">
<column autoIncrement="true" name="id" type="BIGSERIAL">
<constraints primaryKey="true" primaryKeyName="PK_testmy"/>
</column>
<column name="created_at" type="TIMESTAMP(6) WITHOUT TIME ZONE"/>
<column name="employee_id" type="BIGINT"/>
</createTable>
</changeSet>
<changeSet author="liquibase-docs" id="sql-example">
<sqlFile dbms="postgresql" encoding="utf8" path="testmy.sql" relativeToChangelogFile="true"/>
</changeSet>
testmy.sql file contain:
ALTER TABLE testmy
ADD COLUMN began_at INTERVAL ,
ADD COLUMN ended_at INTERVAL ;
Could anyone show another variant to solve such problem?

addUniqueConstraint with where clause in liquibase

I want to convert this sql query
CREATE UNIQUE INDEX UNQ_ALERT_NAME
ON alert_configuration(name, account_id)
WHERE
(status != 'Deleted')
to liquibase changeset like given below
<changeSet author="kusum" id="alertconfig-unique-index-4.1.0"">
<addUniqueConstraint
columnNames="name, account_id, tournament_id"
constraintName="UNQ_ALERT_NAME"
tableName="alert_configuration"
/>
</changeSet>
Not sure where this "where clause" could be added for addUniqueConstraint? Any help is appreciated.
There is no liquibase syntax for this so you have to use the SQL tags:
<changeSet author="kusum" id="alertconfig-unique-index-4.1.0"">
<SQL> CREATE UNIQUE INDEX UNQ_ALERT_NAME
ON alert_configuration(name, account_id)
WHERE
(status != 'Deleted') </SQL>
</changeSet>