In liquibase there is a possibility to define <property>, but it's constant.
Is there any ability to define some variable for <databaseChangeLog>, which is the result from SQL query?
<databaseChangeLog>
<!-- something like this -->
<property name="variable" query="SELECT id FROM Table WHERE name='test'" type="SQL"/>
<changeSet>
<update tableName="Table">
<column name="columnName" value='text'/>
<!-- and below use ${variable} -->
<where>id="${variable}</where>
</update>
</changeSet>
</databaseChangeLog>
Related
I am trying to populate 2 tables through csv files in liquibase.
I have one table called tenant and one another named tenant_configuration and have foreign key to tenant. First part is load tenant data:
<changeSet id="1" context="test">
<comment>Insert data for tenant table</comment>
<loadUpdateData
primaryKey="id"
file="tenant.csv"
tableName="tenant"/>
</changeSet>
Then i would like to use another csv file to populate tenant config but retrieve tenant_id from first change.
<changeSet id="2" context="test">
<comment>Insert data for tenant_db_configuration table</comment>
<loadData tableName="tenant_db_configuration"
file="tenant_db_configuration.csv"
separator="," >
<column name="tenant_id" type="NUMERIC" defaultValueComputed="(SELECT ID FROM tenant WHERE tenant_id = tenant_1)"/>
<column header="username" name="username" type="STRING"/>
<column header="password" name="password" type="STRING"/>
</loadData>
</changeSet>
Tried this but liquibase ignore the tenant_id part and shows:
[Failed SQL: INSERT INTO [dbo].[tenant_db_configuration] ([username], [password]) VALUES...
how i can retrieve that foreign key and merge with existing csv file to load data?
thanks!
As far as i know you will need to make the relation manually in the secomnd CSV file, tenant_db_configuration.csv. I mean, each row in there will need to be pointing to an existent id in the tenat Table.
If the order doesnt matters bc you trust in your csv data, You could disable the foreign key checks with a changeSet before starting to import the data.
I dunno wich DBMS are you using but with MYSQL is
<changeSet author="liquibase-docs" id="sql-example">
<sql dbms="mysql">
SET FOREIGN_KEY_CHECKS=0;
</sql>
</changeSet>
and then you can enable it after on a separate changeSet.
It's been 3 months since the question, so Hope it helps. If you solved it already, what was the solution?
I have added some new changesets in an existing changelog file and want to execute only 2 among the new inserted ones. When I give the update command in liquibase it updates all the unread changesets and updates the database. But I want to execute only 2 among these newly inserted changesets in the changelog file. Is there any way of doing this in liquibase? If yes how is it possible?
One way you could do this is to mark the relevant changesets with a label, and then use that label in your liquibase update command.
This blog post on labels describes their use.
Here is an example that matches what you described in your comment below.
changelog
<?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="steve" labels="labelOne">
<createTable tableName="tableOne">
<column name="id" type="int" autoIncrement="true">
<constraints primaryKey="true" nullable="false" />
</column>
</createTable>
</changeSet>
<changeSet id="2" author="steve" labels="labelTwo">
<comment>Creating table "tableTwo"</comment>
<createTable tableName="tableTwo">
<column name="id" type="int" autoIncrement="true">
<constraints primaryKey="true" nullable="false" />
</column>
</createTable>
</changeSet>
<changeSet id="3" author="steve" labels="labelThree">
<comment>Creating table "tableThree"</comment>
<createTable tableName="tableThree">
<column name="id" type="int" autoIncrement="true">
<constraints primaryKey="true" nullable="false" />
</column>
</createTable>
</changeSet>
</databaseChangeLog>
command execution
If you wanted to update and only create table one, you would use this command (if you are using the command line, and assuming that you have a liquibase.properties file that specifies all the connection information, etc.)
liquibase --changeLogFile=changelog.xml --labels=labelOne update
If you wanted to apply two changesets, you would use a command like this:
liquibase --changeLogFile=changelog.xml --labels="labelOne and labelTwo" update
I would like to do a liquibase insert with the primary key being auto generated from the sequence defined in the database. The target database is HSQLDB.
It works to do an insert specifying a value for the primary key
<insert ...>
<column name="TAG_ID" valueNumeric="2"/>
I found this (admittedly older) conversation about it but the issue is still the same. The suggested fix doesn't work for HSQLDB.
Looking at the docs I've tried some things like
<column name="TAG_ID" defaultValueSequenceNext="TAG_ID_SEQ" />
<column name="TAG_ID" defaultValueSequenceNext="TAG_ID_SEQ.NEXTVAL" />
<column name="TAG_ID" valueComputed="TAG_ID_SEQ.NEXTVAL" />
<column name="TAG_ID" autoIncrement="true" />
but none of those put anything in the key when I do the insert (the insert fails on a null primary key).
How does one accomplish this?
HSQLDB has a setting to use Oracle syntax. You can set HSQLDB to use oracle syntax like so:
<changeSet ...
<sql dbms="hsqldb" >SET DATABASE SQL SYNTAX ORA TRUE</sql>
</changeSet>
After that, it works to do the insert like this:
<insert ...
<column name="TAG_ID" valueComputed="TAG_ID_SEQ.NEXTVAL"/>
I am implementing a changeset in Liquibase that needs a few different preconditions to be valid before it attempts to run.
Scenario #1: If table A,B,C exists, mark as ran
Scenario #2: If table X,Y,Z doesn't exist, halt execution of changeset
In other words, I need two <preConditions> tags with different onFail clauses. Is this at all allowed in Liquibase? I can't seem to make it work. The docs aren't very informative.
It is not allowed currently. There can be just one block.
Would it work to break it up into two separate changeSets?
Combine them with <or> or <and> like this:
<preConditions>
<or>
<runningAs username="liquibase" />
<runningAs username="sa" />
</or>
</preConditions>
Here is some documentation on preConditions.
A workaround that I've simply used:
create a normal precondition
<!-- pre-condition tests -->
<preConditions onFail="WARN">
<runningAs username="${db.maintenance.user}" />
</preConditions>
create an empty changeSet for another onFail level
<changeSet id="liquibase-pre-1" author="liquibase" runAlways="true" runOnChange="true" runInTransaction="false">
<preConditions onFail="HALT" onFailMessage="...">
<!-- ... -->
</preConditions>
<sql>
select 1 <!-- (Postgresql) or "select 1 from dual" (Oracle) -->
</sql>
</changeSet>
I am looking to compress a column through Liquibase and I haven't been able to find any examples of this on the Liquidbase site.
I was wondering if anyone has an example of this?
You can add custom SQL statements to Liquibase change logs using the <sql> element and use the dbms attribute on change sets to define for which databases they are meant to be run.
<changeSet id=".." dbms="oracle">
<sql>
alter table foobar move compress;
</sql>
<rollback>
<sql>
alter table foobar nocompress;
</sql>
</rollback>
</changeSet>
You can use modifyDataType
<changeSet author="liquibase-docs" id="modifyDataType-example">
<modifyDataType catalogName="cat"
columnName="id"
newDataType="A String"
schemaName="public"
tableName="person"/>
</changeSet>