Is it possible to execute repeatable migrations in flyway even when the checksum is the same? The problem I am facing is having a view which extends another table with additional rows and the view doesn't get updated automatically.
An example here:
R__person_view.sql
CREATE OR REPLACE VIEW person_view AS
SELECT p.*, e.name FROM person p, entity e
WHERE /* not relevant here ... */;
If this migration is executed at first it will work fine. If I add another migration, where I modify the table person, the changes are not adapted, because the view migration checksum did not change.
Yes, from Flyway 6.3.0 it has been possible to have repeatable migrations run each time using the timestamp placeholder in a comment, ensuring that Flyway sees this as being changed afresh each time. For example:
R__UtilityProcedures.sql
-- ${flyway:timestamp}
create or replace procedure my_important_proc
Related
In my liquibase project, I have an sql view that is defined within a file called create_myview.sql.
Each time a change is made to the view, i.e. a column is dropped or renamed, instead of creating a new changeset that contains an ALTER statement, the view definition itself in this file is changed.
This file has the runOnChange attribute set to true so that when changes are made, the view is dropped and recreated the next time liquibase update is run. As such the same file can be run over and over when its contents change, i.e. it is "rerunnable".
Since previous definitions of the view are overwritten with each change, rolling back to a previous version presents a challenge and I am unable to work out the best way to do this.
Currently the only way that I am storing the previous view definitions is through git branches, i.e. with each view change I create a new branch.
Ideally I would like to checkout an old branch and be able to rollback to the definition that is currently checked out. I would like to be able to hop between versions easily.
Other non-rerunnable changesets defined in my project use a --rollback tag that is specified in the sql file and provides the inverse sql operation to each table change i.e. if a column is added to a table using an alter statement, then the inverse sql statement specified looks like:
-- rollback ALTER TABLE x DROP COLUMN name;
The equivalent of using this tag in my rerunnable view file would be to copy the entire previous view definition into this rollback tag, which doesn't seem like it would be best practice.
However, liquibase rollback doesn't seem to work without the --rollback tag being specified.
The file structure:
myDB/
changelog/
ver1/
rerunnable/
create_myview.sql
rerunnable.myDB.xml
myDB.changelog-root.xml
This is how I would make changes and update my view from one version to the next.
checkout new branch
git checkout -b c-01
add changes to view
create_myview.sql:
-- changeset john:c-01 runOnChange:true
DROP VIEW my_view IF EXISTS my_view;
CREATE my_view AS
SELECT name, date
FROM my_table;
...
update the changeset attributes
rerunnable.myDB.xml
<changeSet author="john" id="c-01">
<tagDatabase tag="1.0.0"/>
</changeSet>
Run liquibase update.
Next, an update is made to the view when the date column is dropped.
git checkout -b c-02
-- changeset john:c-02 runOnChange:true
DROP VIEW my_view IF EXISTS my_view;
CREATE my_view AS
SELECT name
FROM my_table;
...
<changeSet author="john" id="c-02">
<tagDatabase tag="2.0.0"/>
</changeSet>
liquibase update
At this point, the view in the database is up to date with the latest update, without the date column, and the databasechangelog looks like:
id
author
orderexecuted
md5sum
description
tag
c-01
john
1
83h8hs...
tagDatabase
1.0.0
c-01
john
2
ln9n2b1...
sql
c-02
john
3
ib309bd...
tagDatabase
2.0.0
c-02
john
4
lmxo21...
sql
From this point I am unable to rollback to how the view was at c-01/1.0.0.
The behaviour that I expect/hope is possible would be something like:
check out branch c-01
the old view definition is now in the working directory
run liquibase rollback or liquibase update
the view in the database is dropped and recreated with the c-01 schema (with the date column).
The changelog only has the first 2 lines.
Unfortunately, liquibase update does nothing, and liquibase rollback specifies that I need a --rollback statement.
would the runAlways attribute work here as a good solution?
For those not on the Liquibase forums, I answered this question there:
https://forum.liquibase.org/t/how-do-i-manage-rolling-back-changes-made-to-rerunnable-runonchange-true-changelogs-that-contain-stored-logic/7780
I currently have a .sql file with the likes of:
DROP VIEW IF EXISTS vw_example;
CREATE VIEW vw_example as
SELECT a FROM b;
When running this command as part of a flyway migration, if the view already exists, it fails, as if the create command is not waiting for the DROP IF EXISTS to finish.
I know SQL server has a GO type keyword. Is there a way to sort of tell cockroachdb to wait for the first command?
As per the issue mentioned in the link, it is better to have the drop and create scripts in different migration files as flyway runs each migration in a single transaction.
Trying to figure out how rollbacks work with formatted SQL and Liquibase.
Working from the quickstart on the Liquibase site, I was able to create a table in my database. Then started working on the rollback. Just as a manual test, once my table was created, I tagged the change in the DATABASECHANGELOG table. Ran Liquibase rollback <mytag> and it said it completed it successfully, but the table wasn't modified.
--liquibase formatted sql
--changeset user:1
create table addresses (
address VARCHAR(45),
city VARCHAR(45),
zip VARCHAR(10)
);
--rollback drop table addresses;
Liquibase said the rollback completed successfully, but the table wasn't dropped.
The tagging concept in Liquibase seems to confuse many people. Tagging is used to mark a known good state, so if you tagged it after deploying a change that created a table, and then said rollback to that tag, it did things 'correctly' in its way of thinking.
Here is the tiny bit of documentation on that (I added the emphasis on after):
Tag
Specifying a tag to rollback to will roll back all change-sets that
were executed against the target database after the given tag was
applied. See the “command line” documentation for how to tag your
database.
To test the rollback of the table in your example, you would need to use the rollbackCount command or the rollbackToDate command.
I wanted to change the data type of one field from string to date. So i dropped the table in db. Then modified the liquibase file and ran the application. now it complains with the following message.
liquibase.exception.ValidationFailedException: Validation Failed:
So after that I reverted the liquibase file changes and ran the application. This time no error but it is not creating the table.
Please help me how to solve this issue.
I assume the failed validation was an error about checksums. This happens when you modify a changeset which was already executed and try to execute it again.
Liquibase keeps all executed changesets in a table called databasechangelog, so it can find out which changesets can be skipped during execution.
To execute a changeset again, delete the corresponding from this table before, and run Liquibase again.
When using Liquibase, you shouldn't (in general) modify the database outside of Liquibase - the main exception being if you are a developer working on your own private development database. If you are in that state (working on your own private database), then when you modify the database outside of Liquibase (i.e. dropping a table) you will also need to delete the row in the DATABASECHANGELOG table that corresponds to the table create statement so that when you re-run liquibase update it will re-create the table.
With the migrate new command, it generates a sql file:
-- // create blog table
-- Migration SQL that makes the change goes here.
-- //#UNDO
-- SQL to undo the change goes here.
Does the command detect my table and data changes and fill in with the script, such as Alter Table query, automatically? Or I have to fill in the scripts manually?
It was answered here:
Migrations does not do any introspection or reverse engineering of
your database. You have to enter the DDL changes your self.