- Versioned migrations run once, in a strict order, and never again.
- Repeatable migrations can run multiple times — they’re re-applied whenever the file changes.
They serve different purposes in managing your database schema.
🔍 Detailed Comparison
| Feature | Versioned Migrations | Repeatable Migrations |
|---|---|---|
| File Naming | V1__create_users.sql | R__refresh_views.sql |
| Execution Count | Once | Re-applied when content changes |
| Use Case | Schema evolution | Views, stored procedures, seed data |
| Tracked By | Version number (V1, V2, etc.) | Description (e.g., R__refresh_data) |
| Checksum Sensitivity | Errors if checksum changes (unless repaired) | Triggers re-execution if checksum changes |
| Execution Order | Strict version order (1 → 2 → 3…) | After all versioned migrations |
| Can be undone? | ✅ (with U__undo.sql) | ❌ (not supported by default) |
🧪 Example — Versioned Migration
V1__create_users_table.sql
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100)
);
✅ Runs once, logged in flyway_schema_history, never runs again unless manually repaired or rolled back.
🧪 Example — Repeatable Migration
R__create_views.sql
CREATE OR REPLACE VIEW active_users AS
SELECT * FROM users WHERE active = true;
✅ Will re-run any time this file changes (checksum is re-calculated on each migrate)
🔄 When Do Repeatable Migrations Run?
- After all versioned migrations
- If:
- The file content changed (checksum mismatch)
- It has never run before
📌 Key Takeaways
✅ Use versioned migrations for all structural schema changes (tables, columns, constraints)
✅ Use repeatable migrations for redefinable objects (views, stored procedures, triggers, seed data)
✅ Repeatables help you keep non-critical DDL up-to-date across environments