Fix Flyway Repeatable Migration – Not Re-applying
In this tutorial, you'll learn about Fix Flyway Repeatable Migration. We cover key concepts, practical examples, and best practices.
You create a repeatable migration R__my_view.sql, and it runs successfully on the first flyway migrate. You modify the file and run flyway migrate again — but Flyway says "No migration necessary". The view wasn't updated.
Wrong ❌
-- R__active_users_view.sql
CREATE OR REPLACE VIEW active_users AS
SELECT * FROM users WHERE status = 'active';
flyway migrate
# First run: Successfully applied R__active_users_view.sql
You edit the file:
-- R__active_users_view.sql (modified)
CREATE OR REPLACE VIEW active_users AS
SELECT id, name, email FROM users WHERE status = 'active';
flyway migrate
# Output: Current version of schema "public": 5
# No migration necessary — already up to date.
Flyway didn't re‑apply R__active_users_view.sql. Your view change didn't deploy.
Right ✅
Check the checksum comparison:
Flyway re‑applies a repeatable migration only if its checksum changes compared to the last run. Check the current checksum:
SELECT version, description, checksum, installed_on
FROM flyway_schema_history
WHERE type = 'REPEATABLE';
If the new file has the same checksum (e.g., whitespace‑only changes), Flyway won't re‑run it. Ensure the change is meaningful.
Force re‑apply:
We don't recommend it, but for development:
flyway migrate -repeatableSqlMigrationPrefix=R_
# Still won't run if checksum is the same
To force re‑apply, delete the row:
DELETE FROM flyway_schema_history
WHERE type = 'REPEATABLE' AND version IS NULL;
Then flyway migrate will re‑apply all repeatable migrations.
Check the correct prefix:
# flyway.conf
flyway.repeatableSqlMigrationPrefix=R_
# Default is R__
Ensure the prefix matches your filename.
Order of execution:
Repeatable migrations always run after versioned migrations on the same flyway migrate invocation. They also run in alphabetical order by description.
V1__create_users.sql
V2__add_index.sql
R__active_users_view.sql ← runs after V2
R__inactive_users_view.sql ← runs after R__active_users_view
If R scripts don't run after a versioned migration that they depend on:
-- V3__add_deleted_column.sql
ALTER TABLE users ADD COLUMN deleted_at TIMESTAMP;
-- R__active_users_view.sql — references deleted_at
After applying V3, run flyway migrate again:
Successfully applied R__active_users_view.sql (checksum changed ✅)
Root Cause
Repeatable migrations re‑apply only when their content changes (checksum differs). Whitespace‑only changes don't change the checksum. If you forget to re‑run flyway migrate after editing an R script, the change isn't deployed.
Prevention
- Always run
flyway migrateafter editing a repeatable migration. - Make substantive changes — not just whitespace or comments.
- Use
flyway infoto see whether the repeatable migration checksum matches the current file. - In CI, always run
flyway migrate— it's idempotent and fast when nothing changed.
Common Mistakes with repeatable migration
- Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors
- Non-exhaustive pattern matches that compile with warnings then crash at runtime
- Misunderstanding that
Stringis[Char]with poor performance for large text operations
These mistakes appear frequently in real-world FLYWAY code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Repeatable migrations are covered in the DodaTech Flyway Advanced course.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro