What is the best way to rename index in liquibase? should I delete and recreate it?
thanks in advance.
At first, you must remove former index:
<changeSet id="20210905084713-2" author="ARMIN.NOROOZIAN">
<dropIndex tableName="tpl_order" indexName="tracking_code_idx"/>
</changeSet>
Then create a new index:
<changeSet id="20210905084713-3" author="ARMIN.NOROOZIAN">
<createIndex tableName="tpl_order" indexName="tpl_tracking_code_idx">
<column name="tpl_tracking_code"/>
</createIndex>
</changeSet>
Related
The Setup
I am using Liquibase to manage my project's migrations.
I have several tables with several sets of seed data.
Each seeded table has a changeset to create the table, followed by a changeset to load the seed data. The seeds are being loaded using loadUpdateData. This is a smart method that will load seed data from a CSV, if the CSV content is edited it will make the appropriate edits directly.
The seed ChangeSets are in a separate ChangeLog that is always run after the core ChangeLog. This way the seed files can always reflect the correct table structure.
The Problem
I need to drop a table that has seed data. The loadUpdateData command errors because the table no longer exists by the time it is run.
The Code
Create Table ChangeSet
<changeSet author="" id="create-table-help-items">
<createTable tableName="help_items">
<column name="help_item_id"
type="bigint">
<constraints primaryKey="true"/>
</column>
<column name="title"
type="text" />
<column name="description"
type="text" />
</createTable>
<rollback>
<dropTable tableName="help_items"/>
</rollback>
</changeSet>
Seed ChangeSet
<changeSet author="" id="seed-help-items" runOnChange="true">
<loadUpdateData file="db/seeds/help_items.csv"
primaryKey="help_items_id"
tableName="help_items" />
</changeSet>
Drop Table ChangeSet
<changeSet author="" id="remove-table-help-items">
<dropTable tableName="help_items"/>
<rollback changeSetId="create-table-help-items" changeSetAuthor=""/>
</changeSet>
The Questions
Given that it is bad practice to ever delete changesets from a changelog.
What is the right way to create seed migrations so that they don't break when the table is deleted?
Do I need to keep the seed files for tables that have been dropped?
I had the same problem and now i solved it, it works already by me.
The point is that you should set the Rollback in "Drop Table ChangeSet" correctly.
So by droping a table, you should already prepare for the situation of rollback.
<changeSet author="" id="remove-table-help-items">
<dropTable tableName="help_items"/>
<rollback>
<createTable tableName="help_items"/>
</rollback>
</changeSet>
I solved this issue by setting runAlways: false for loadUpdateData changeset. So, it doesn't fail when the table is dropped.
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 a changeset to create an index.
<changeSet author="hilland" id="x-NC-U-y" runOnChange="true">
<createIndex indexName="NC-U-y" tableName="x" unique="true">
<column name="y"/>
</createIndex>
<rollback>
<dropIndex .../>
</rollback>
<modifySql>
<append value=" INCLUDE ( [a],[b]) WITH (DATA_COMPRESSION=page)"/>
</modifySql>
</changeSet>
The problem is that an older version of the index might exist (it will on some targets (dev server, with an older version of this index; no includes), will not on others (eg a fresh deploy to an empty database).
Is there a better way to resolve this so that the script becomes universal, than to include a prefix which says
<sql>IF select {sys.indexes.stuff} is not null {drop the index}</sql>?
Ideally there would be a precondition to drop-if-exists the existing index so that it can be recreated, but i don't think that can be done.
What is the best way to handle this situation?
an alternate solution i thought of would be to have a separate changest "if index v1 exists, drop it" then have a separate v2 changeset, but then that would make rollback hard.
I realize that the run on change condition for the changeset makes rollback hard, but the only rollback i'm concerned with in this case is to and from an empty database, although a pattern which easily accommodates rollbacks to previous version would be welcome also.
You can execute changesets dependent on a precondition. Your changeset could look like this:
<changeSet>
<preConditions onFail="MARK_RAN">
<indexExists indexName="NC-U-y" />
</preConditions>
<dropIndex indexName="NC-U-y" />
</changeSet>
See also the Liquibase Documentation.
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>
I have an existing mysql table with two columns a and b.
I now want to add a column c to that table.
c should be nullable, should have a default value of NULL, except in those rows where column b has the value 10. Where b has the value 10, c should have a value X.
I understand that it is fairly simple to do this using SQL, but I want to do this using liquibase, since liquibase is what we use for our schema migrations.
Have you already tried something like this?
<addColumn tableName="SGW_PRODOTTI_INFO_ATTRIBUTE">
<column name="AlternativeListPrice" type="double" defaultValue="0.0">
<constraints nullable="true"/>
</column>
</addColumn>
I think the best solution without using plain sql is following:
Use addColumn change, as Walter wrote;
Use update change.
You can choose to use both changes within a changeset, but a good practice is to separate each one by a separated changeset for liquibase transaction/rollback purposes.
If you are adding column then
<changeSet author="your-name" id="your-id">
<addColumn tableName="person" >
<column name="is_active" type="varchar2(1)" defaultValue="Y" />
</addColumn>
</changeSet>
add-column
if column is already added, and then you need to set default value
<changeSet author="your-name" id="your-id">
<addDefaultValue columnDataType="varchar2(1)" columnName="is_active" defaultValue="Y" tableName="person"/>
</changeSet>
add-default-value