Reputation: 1677
I looked at the Flyway samples and documentation and tried to understand if it is useful in my environment. The following conceptual detail is unclear to me: How does Flyway manage the changes between database versions? It obviously does NOT compare database life-instances (see answer here:Can Flyway find out and generate migration files from datamodel?)
In detail my setup looks like this: I create SQL create and insert scripts when coding (automatically and manually). This means every version of my database is represented by a number of insert/create statements. In my world I execute these scripts through a database tool (sqlplus from Oracle). Each run would setup the database _from_scratch_ (!).
Can I put these very same scripts 1 to 1 inside the "migration" path of Flyway? What happens if the target database is way older than the last "migration step" I did (or flyway did not yet exist when it was installed)?
I got some input from another Flyway user:
It seems like each "migration" (version of the database) has to be hand-written SQL/Java code and contains only "updates" from the previous "migration" of database.
If this is true, I wonder how this can be used with traditional coding technics: in my world SQL statements are generated automatically and contain all database init/create statements, not just "updates" to some previous version. If my SQL code generator could do that, then I wouldn't even need a tool like Flyway :-).
Upvotes: 6
Views: 5474
Reputation: 1
DECLARE
story_name VARCHAR2(100) := 'Inserting data into SYS_PARM table with ACS Transactions related information';
expected_pre_result PLS_INTEGER := 0;
expected_post_result PLS_INTEGER := 7; -- Assuming there are 7 records to be inserted
prevalidation_failed_msg VARCHAR2(250) := 'Prevalidation for ' || story_name || ' failed. Expected result: ' || expected_pre_result;
postvalidation_failed_msg VARCHAR2(250) := 'Postvalidation for ' || story_name || ' failed. Expected result: ' || expected_post_result;
pre_result PLS_INTEGER := 0;
post_result PLS_INTEGER := 0;
prevalidation_failed EXCEPTION;
postvalidation_failed EXCEPTION;
unexpected_error EXCEPTION;
PRAGMA EXCEPTION_INIT(prevalidation_failed, -20000);
PRAGMA EXCEPTION_INIT(postvalidation_failed, -20001);
PRAGMA EXCEPTION_INIT(unexpected_error, -20002);
BEGIN
-- Pre-validation SQL: Check the initial count of records in SYS_PARM table
SELECT COUNT(*) INTO pre_result FROM MCSENDPERF_OWNER.SYS_PARM;
-- Test for expected pre_result
IF pre_result = expected_pre_result THEN
-- Insert data into SYS_PARM table
INSERT INTO MCSENDPERF_OWNER.SYS_PARM (PARM_TYPE_NAM, PARM_NAM, PARM_VAL) VALUES ('PERF_POC_BATCH', 'PARTNER_ID', '123,456,8831');
INSERT INTO MCSENDPERF_OWNER.SYS_PARM (PARM_TYPE_NAM, PARM_NAM, PARM_VAL) VALUES ('PERF_POC_BATCH', 'AMOUNT', '120');
INSERT INTO MCSENDPERF_OWNER.SYS_PARM (PARM_TYPE_NAM, PARM_NAM, PARM_VAL) VALUES ('PERF_POC_BATCH', 'PRCSSR_ID', '90000022922');
INSERT INTO MCSENDPERF_OWNER.SYS_PARM (PARM_TYPE_NAM, PARM_NAM, PARM_VAL) VALUES ('PERF_POC_BATCH', 'DAILY_LIMIT_CURR_NUM_CD_TXT', '986');
INSERT INTO MCSENDPERF_OWNER.SYS_PARM (PARM_TYPE_NAM, PARM_NAM, PARM_VAL) VALUES ('PERF_POC_BATCH', 'ACT_NUM', '541311313131331');
INSERT INTO MCSENDPERF_OWNER.SYS_PARM (PARM_TYPE_NAM, PARM_NAM, PARM_VAL) VALUES ('PERF_POC_BATCH', 'MAX_ACS_TRANSACTION_COUNT', '10');
INSERT INTO MCSENDPERF_OWNER.SYS_PARM (PARM_TYPE_NAM, PARM_NAM, PARM_VAL) VALUES ('PERF_POC_BATCH', 'SNGL_DUAL_MSG_CD', 'SINGLE');
-- Post-validation SQL: Check the count of records in SYS_PARM table after insertion
SELECT COUNT(*) INTO post_result FROM MCSENDPERF_OWNER.SYS_PARM;
-- Test for expected post_result
IF post_result = expected_post_result THEN
-- Post-validation check passed
DBMS_OUTPUT.PUT_LINE('Data inserted successfully into SYS_PARM table.');
ELSE
-- Post-validation check failed
RAISE_APPLICATION_ERROR(-20001, postvalidation_failed_msg || '. Actual result was ' || post_result);
END IF;
-- Commit the transaction
COMMIT;
DBMS_OUTPUT.PUT_LINE('Change applied');
ELSE
-- Pre-validation check failed
RAISE_APPLICATION_ERROR(-20000, prevalidation_failed_msg || '. Actual result was ' || pre_result);
END IF;
EXCEPTION
WHEN prevalidation_failed THEN
ROLLBACK;
RAISE;
WHEN postvalidation_failed THEN
ROLLBACK;
RAISE;
WHEN OTHERS THEN
ROLLBACK;
DBMS_OUTPUT.PUT_LINE('Unknown error occurred. Rollback executed');
RAISE_APPLICATION_ERROR(-20002, 'An unexpected error was encountered for ' || story_name || '. SQLERRM: ' || SQLERRM);
END;
Upvotes: 0
Reputation: 1091
Your question about "how to handle a DB that has a longer history than there are migration scripts?" You need to create a V1_ migration/sql script that matches/recreates your latest DB schema. Something that can take a blank DB to what you have today. Create/generate that sql script using your existing DB tools and then put it in flyways migration directory. (And test V1 by using flyway against a clean DB and see if you get what you expect.) http://flywaydb.org/documentation/existing.html
After that point in time, all later versions must be added in as you work. When you decide you need a new table, in your dev environment, write a new V*_.sql that modifies your schema to the way you need it.
This blog goes over this situation for a Spring/SQL application. https://blog.synyx.de/2012/10/database-migration-using-flyway-and-spring-and-existing-data/
Upvotes: 4