á€áá±á¬ááºážáá«ážááœáẠá¡áá¯á¶ážáá»ááŸá¯ááœáẠáá±áá¬áá±á·á Ạááá¯ááºáááºáá®ááŸá¯ááá¯ááºáᬠááŒá¿áá¬áá»á¬ážááᯠáááºááá¯á·ááŒá±ááŸááºážááááºááᯠá¡áá±ážá ááẠááŸááºážááŒáá¬ážáááºá á¡áááºá áááºááẠááá¬áááŒááºáááºááŸá¯áááŸááá² ááŒáá·áºáá»ááºáááºááŒáá¯ážá á¬ážáá«á áááºááá¯ááºáá¯ááºáá±ážá¡ááºááá®áá±ážááŸááºážáá»á¬ážááœáẠáá¬ááŒá áºááá¯ááºáááºááᯠáá»áœááºá¯ááºááá¯á·ááŒá±á¬ááŒáá«áááºá ááá¯á·áá±á¬áẠáá»áœááºá¯ááºááá¯á·ááẠáá¯á¶ážáá ááºáááºááẠááá¯á¡ááºáá±á¬ áá»áŸá±á¬ááºááœáŸá¬ááá ááºáááºážá¡ááá·áºáá»á¬ážááᯠááŒááºáááºážááœá¬ážáá«áááºáá¡áá®ážá ááºáá¯á¶áž áááºážááŒá±á¬- áá±á¬ááºááẠ- áá¯á á ááºáááºáá»áááº) áá»áœááºá¯ááºááá¯á·ááá¯ááºáá±á¬ááºááŸá¯áá»á¬ážáááááºááẠáá±á¬ááºááŒááº-áááá¬ááááŒá áºáá±á¬áá±áá¬áá±á·á áºááŒá±á¬ááºážáá²ááŸá¯ááᯠáá±á¬ááºááŒááº-áááá¬áááŒá áºá á±áá±á¬áá¯á¶á á¶ááŒáá·áº á¡áá¯á¶ážááŒá¯áááºááŒá áºáááºá
áá±á¬ááºážáá«ážá០áá¯ááºááá°áá¬áá»á¬ážááᯠáá¬ážáááºááá¯áá«á áááºážááá¯á·ááᯠááœáẠááŸá¬ááœá±ááá¯ááºáá«áááºá
áááá«ááºáž
á ááºáááºáá»ááẠáá¯á¶ážááááŸáááŒááºážá
áááá·áºááᯠáááºážááŒááºáá«áááºá á ááºáááºáá»ááẠááŒáá·áºáá»ááºááŸá¯ áá¯á? ááá·áºá¡ááá®áá±ážááŸááºážááᯠáá¯ááºáá¯ááºááŸá¯ááœáẠáá¬ážááŸááºážá¡áá áºááᯠá¡á±á¬ááºááŒááºá áœá¬ááááºáááºááá¯ááºá á±ááá·áºáááºážáááºážááŒáá·áº ááá·áºá¡ááºááºáá®áá±ážááŸááºážááᯠá¡áá¯á¶ážááŒá¯ááá·áºá¡áá«ááœáẠáááºážááẠá¡áá¯á¶ážááŒá¯áá°áááááŸáááá¯ááºááŸá¯ááᯠáááááá¬ážáááá² ááŒá áºáááºáᯠáááºááŒá±á¬ááá¯ááºáááºá á¡áá¯á¶ážááŒá¯áá°ááŸáá·áº áá¯áá¹ááá®ááŸá¯áá±á¬áá·áºááŸááŒáá·áºáá»áŸáẠáááºážááẠá¡ááºá¹áá«áááºá¡áá áºáá»á¬ážááᯠááááºáááºáááºááŸáá·áº á¡ááŸá¬ážá¡ááœááºážáá»á¬ážááᯠá¡ááŸá±á¬áá·áºá¡ááŸááºáááŸááá² ááŒááºáááºááá¯ááºáá±á¬ááŒá±á¬áá·áº ááŒá áºááá¯ááºááá·áº á¡áá±á¬ááºážáá¯á¶ážá¡áá¯á¶ážáá»ááŸá¯á¡ááŒá±á¡áá±ááŒá áºáááºá
áá«ááᯠá¡á±á¬ááºááŒááºá¡á±á¬áẠáááºááá¯áá¯ááºááá²á áááºážáááºážáá»á¬ážá áœá¬ááŸááá«áááºá áááºážááá¯á·áá²ááŸáá áºáá¯ááŒá áºáááºá
- ááá·áºáááºáá±á¬ááºááŸá¯á áá¬ážááŸááºážáá¶áá«áẠ1 ááᯠá¡áá¯á¶ážááŒá¯áá«á
- áá±áá¬áá±á·á ẠááœáŸá±á·ááŒá±á¬ááºážááŒááºážááᯠáá¯ááºáá±á¬ááºáá«á
- ááá·áºáááºáá±á¬ááºááŸá¯á áá¬ážááŸááºáž #2 ááᯠáá¬ážááŸááºáž #1 ââááŸáá·áº á¡ááŒáá¯áẠá¡áá¯á¶ážááŒá¯áá«á
- áá¶áá«áẠ2 áá¬ážááŸááºážááᯠáááºááœá±á·ááŒááºááŒá®ážáááºááŸáá·áº áááºážááẠááá·áºá¡áá±ááŒáá·áº áá¬ážááŸááºážáá¶áá«áẠ1 ááᯠáááºááŸá¬ážááá¯ááºáá«á
- á¡áááºáááºá·!
ááœááºáááºááá¯ááºáá¬áž áá¶ááá±á¬ááºážá áœá¬ááŒáá·áºá áááºážááẠááá¯áá»áŸáááá¯ážááŸááºážáá«á áááºážááᯠáá±á¬ááºááá¯ááºážááœáẠá¡áá±ážá áááºááŒáá·áºááŸá¯áá«áááºá ááᯠáá±á¬ááºááẠáá»áŸáá»áŸáá á¡áá¯á¶ážáá»á¬ážáá±á¬ á¡áá¯á¶ážáá»ááŸá¯ áá¯ááºáááºážá áẠ- á¡ááŒá¬áá±á¬áẠá¡á áááºážáá±á¬áẠááŒáá·áºáá»ááºááŸá¯ááᯠá á áºáá±ážááŒáá·áºáá¡á±á¬ááºá
ááŒá¬ážáá°ážáá¬áž
- ááá·áºáá¯ááºáá¯ááºáá±ážáá¯ááºáááá¹áá° (âá¡ááŒá¬â ááŸáá·áº âá¡á áááºážáá±á¬ááºâ) á¡áá¯ááºáá¯ááºááŒá±á¬ááºáž áá±áá»á¬áá«á á±á
- á¡ááŒá¬áá±á¬ááºáááºáááºážáá»ááºááá¯á· á¡ááœá¬ážá¡áá¬á¡á¬ážáá¯á¶ážááᯠááœáŸááºááŒáá±ážáááºá i.e. áá¯ááºáá¯ááºááŸá¯ URL áá»á¬ážááẠááá¯áá±áá¬ááœáẠááœáŸááºááŒáááºá
- á áááºážáááºážáá±á¬áááºáááºážáá»ááºááœáẠá¡ááá®áá±ážááŸááºážááŒá±á¬ááºážáá²ááŸá¯á¡á¬ážáá¯á¶ážááᯠá¡áá¯á¶ážáá»ááŒá®áž á ááºážáááºáá«á
- url áá»á¬ážááᯠá¡ááŒá¬á០á¡á áááºážáá±á¬ááºáááºáááºážáá»ááºááá¯á· ááŒá±á¬ááºážáá«á
á¡ááŒá¬áá±á¬áẠá¡á áááºážáá±á¬áẠááŒáá·áºáá»ááºááŒááºážááẠáá¯ááºáá¯ááºááŸá¯ ááŒáá¯ááœá²áááºááᯠá áá¯ážááááºá áá¬áááá¯áá² áááºáá±á¬ááºááŸá¯á¡áá áºáá»á¬ážááᯠá¡ááœááºááá° ááááºáááºááá¯ááºá á±ááá·áº áááºážáááºážáá áºáá¯ááŒá áºáááºá áá«á áá áºáá¯áá¯ááŒá áºááœá¬ážáááºáá±á¬áẠ"ááá¯ááºááᯠááŸáááºááá¯ááºáá¯á¶áá²á·" ááááºáááºáááºážáá»ááºááᯠá¡ááœááºááá° ááŒááºááŸáá·áºááá¯ááºáá¬ááŒá±á¬áá·áºáá«á
á¡áááºáá±á¬áºááŒáá« á¡á¬ážáá¯á¶ážááᯠáááºááŸá¯ááŒá®ážáá±á¬ááºá á¡ááŒá¬áá±á¬áẠá¡á áááºážáá±á¬áẠááŒáá·áºáá»ááºááŒááºáž ááŸáá·áº áááºáááºááá·áº áá¯á á ááºáááºááŒááºáž ááẠá¡áááºá¡áá¬ááŸáá·áº áááºááá¯ááºááááºážá
áá°áá®áá±á¬áááºáááºážáá»ááºá áááá¹áá°ááŸá
áºá
á±á¬ááºááᯠááááºážááááºážáá¬ážááẠáááºážááá¯á·á¡á¬áž ááááºážááááºážááẠá¡á¬ážáá¯ááºááŸá¯ ááŸá
áºáááá¯á¡ááºáá±á¬ááŒá±á¬áá·áº áááºážááá¯á·ááœáẠáá°áá®ááŸá¯áá»á¬ážá
áœá¬ááŸááááºá á¡á²áá«ááŒá±á¬áá·áº ááá»áá¯á·á¡áááºážááœá±á áá±á¬ááºážááá¯áááºá
á¡ááŒá¬ážááœá±ážáá»ááºá áá¬ááŸá¬ áááºááŸáá·áº ááá¯ááááºážá¡ááœáŸá¬áá»á¬ážá¡ááœáẠá¡á áááºážáá±á¬ááºá¡ááŒá¬áá±á¬ááºááá¯ááºáá»á¬ážááᯠáááºáá®ážáᬠáá°áá®áá±á¬áá±áá¬áá±á·á áºááᯠá¡áá¯á¶ážááŒá¯áááºááŒá áºáááºá á€áá»ááºážáááºááŸá¯ááœááºá á¡áá°ážáááŒáá·áº áá±á¬á·ááºáá²ááºáá¬ážááŸááºážá¡áá áºááᯠáá¶á·ááá¯ážááẠáááºážá schema ááᯠááŒá±á¬ááºážáá²ááẠááá¯á¡ááºááá·áºá¡áá«ááœáẠáá±áá¬áá±á·á áºááẠáááŒá¬áá ááŒá¿áá¬ááŒá áºááá¯ááºáááºá
á€ááœáẠá€áá±á¬ááºážáá«ážááœáẠá¡áááááŒá¿áá¬ááᯠáá»áœááºá¯ááºááá¯á· áá±á¬ááºááŸááá¬áá«áááºá áá±áá¬áá±á·á . áá®á áá¬ážá á¯ááᯠáá±á¬ááºáá áºáá»áá¯áž áá±á·áá¬ááŒáá·áºáá¡á±á¬ááºá
áá±áá¬áá±á·á ẠááœáŸá±á·ááŒá±á¬ááºážááŒááºážááᯠáá¯ááºáá±á¬ááºáá«á
ááᯠááá·áºááá¯ááºááẠáá±ážáááá·áºáá±ážááœááºáž - áá±áá¬áá±á·á áºááŒá±á¬ááºážáá²ááŸá¯ááẠáá±á¬ááºááŒááºáááá¯ááºááá¯ááºáá«á áááºááá¯á·áá¯ááºáá±á¬ááºáááºáááºážá áá»áœááºá¯ááºá ááááá¯á¶áž á¡ááºááºáá¬ážááŸááºáž áá»ááºáááºááá¯ááºáá«áá¬ážá á¡ááŸááºáá±á¬á· áá«á ááááºááŒá áºáá¬ááŸá¬áá«...
ááá¯á·ááŒá±á¬áá·áºá áá¯á¶ážáá ááºáááºááŒááºáž/á¡ááŒá¬áá±á¬ááºá¡á áááºážáá±á¬ááºááŒáá·áºáá»ááºááŒááºážá ááŒá®ážáá¬ážáá±á¬á¡áá»áá¯ážáá»á±ážáá°ážáá»á¬ážááŸááá±áá±á¬áºáááºážá áá¯áá¹ááá®áá»á¬ážááẠáááºážááá¯á·áá¡ááºááºáá®áá±ážááŸááºážáá»á¬ážááá¯á¡áá¯á¶ážááŒá¯áááºá¡ááœááºá¡á±á¬ááºáá«ááá¯ááá¯áá±ážáááºážáá±á¬áá¯ááºáááºážá ááºáá»á¬ážááá¯ááá¯ááºáá¬ááŒáá«áááºá
- á¡ááá®áá±ážááŸááºážáá¬ážááŸááºážá¡áá áºááŒáá·áº áááºáá±á·ááºá»áá áºáá¯ááᯠááŒááºáááºáá«á
- áááºáááºáá±áá±á¬ application ááá¯ááááºáá«á
- áá±áá¬áá±á·á áºááá¯ááŒá±á¬ááºážááœáŸá±á·ááẠscripts áá»á¬ážááᯠrun áá«á
- á¡áá¯á¶ážáá»ááŒá®áž á¡ááá®áá±ážááŸááºážá áá¬ážááŸááºážá¡áá áºááᯠá áááºáá«á
á€áá±á¬ááºážáá«ážááœááºá áá¯á¶ážáá ááºáááºááœá¬ážááŒááºážá á¡áá»áá¯ážáá»á±ážáá°ážááá¯ááá°ááẠááá·áºáá±áá¬áá±á·á áºááŸáá·áº áá¯ááºááŒáá·áº áááºááá¯á·áá¯ááºáá±á¬ááºááá¯ááºááŒá±á¬ááºáž á¡áá±ážá áááºáá±á¬áºááŒáá«áááºá
áá±áá¬áá±á·á ááŒá¿áá¬áá»á¬áž
ááá·áºááœááºáá±áá¬áá±á·á áºááœááºáááºááá·áºáá±áá¬ááá¯áá»áŸáááááºážáááºážááá¯ááºáá±á¬ááá¯ááºáá¶áá²á·á¡ááºááá®áá±ážááŸááºážáá áºáá¯ááŸááá«áá áááºáááºáá»ááºáá»ááºážá ááºáááºáá»áááºá¡áá¯á¶ážááŒá¯ááŸá¯ááá¯áá¯á¶ážááááá¯ááºáááºá áá¶ááá±á¬ááºážá áœá¬ááŒáá·áºá áá±á¬á·ááºáá²á¡áá»á¬ážá á¯ááẠáá áºáá±áá¬áá¬ááœáẠáá±áá¬ááááºážáááºážááẠááá¯á¡ááºáá«áááºá ááá¯á·ááŒá±á¬áá·áº circuit ááá¯ááŒá±á¬ááºážáá²ááŒááºážáááŒá¯áá® ááŸá áºááŒáááºá ááºážá á¬ážááá·áºáá«áááºá á¡áá»áááºáááá¯ááºážáá² ááŒáá·áºáá»ááºááŸá¯áááŒá áºááá¯ááºá á±ááẠschema ááá¯áááºááá¯á·ááŒá±á¬ááºážáá²ááááºáááºážá¡áá±ážá áááºá¡áá»ááºá¡áááºáá»á¬ážááᯠáá»áœááºá¯ááºááá¯á·ááá±á·áá¬áá®á áá¬ážááŸááºážáá±ážááœá²ááŒááºážá¡á á®á¡á ááºááᯠáŠážá áœá¬á¡á¬áá¯á¶á áá¯ááºááŒáá«á áá¯á·á
áá¬ážááŸááºážáá±ážááœá²ááŒááºážá¡á á®á¡á ááº
á€áá±á¬ááºážáá«ážááœááºáá»áœááºá¯ááºááá¯á·á¡áá¯á¶ážááŒá¯áá«áááºá classpath:db/migration
) á€áá±áá¬ááœáẠááá¯áá²á·ááá¯á·áá±á¬ ááœáŸá±á·ááŒá±á¬ááºážááŒááºážááá¯ááºáá»á¬ážá á¥ááá¬ááᯠáááºááœá±á·ááá¯ááºáá«áááºá
âââ db
âââ migration
âââ V1__init.sql
âââ V2__Add_surname.sql
âââ V3__Final_migration.sql
âââ V4__Remove_lastname.sql
á€ááá°áá¬ááœáẠááááºá ááá¯ááºáá±á¬ááºáá«áá á¡ááá®áá±ážááŸááºážá
áááºáá±á¬á¡áá« áá
áºáá¯ááŒá®ážáá
áºáá¯áá¯ááºáá±á¬ááºááá·áº migration scripts 4 áá¯ááᯠáá»áœááºá¯ááºááá¯á·ááœá±á·ááŒááºááááºá ááá¯ááºááœá±áá²á áá
áºáá¯ááᯠááŒáá·áºáá¡á±á¬áẠ(V1__init.sql
) á¥ááá¬áá
áºáá¯á¡áá±áá²á·á
CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);
insert into PERSON (first_name, last_name) values ('Dave', 'Syer');
á¡áá¬á¡á¬ážáá¯á¶ážááẠááŒá®ážááŒáá·áºá
á¯á¶áá±á¬ ááá¯ááºááá¯ááºááŸááºážááŒááŒááºážááŒá
áºáááº- ááá·áºáá±áá¬áá±á·á
áºááᯠáááºááá¯á·ááŒá¯ááŒááºááá·áºáááºááᯠáááºááŸááºááẠSQL ááᯠá¡áá¯á¶ážááŒá¯ááá¯ááºáááºá Spring Boot ááŸáá·áº Flyway á¡ááŒá±á¬ááºážááá¯ááá¯ááááŸáááá¯áá«áá áááºáá±á¬ááºááŒáá·áºááŸá¯áá«á
Spring Boot ááŒáá·áº áááºážááŒá áºááááºážáá»á¯ááºáááááá¬ááᯠá¡áá¯á¶ážááŒá¯ááŒááºážááŒáá·áº áááºááẠá¡áá»áá¯ážáá»á±ážáá°ážááŒá®áž 2 áá¯ááᯠáááŸááááº-
- áááºááẠáá±áá¬áá±á·á áºááŒá±á¬ááºážáá²ááŸá¯áá»á¬ážááᯠáá¯ááºá¡ááŒá±á¬ááºážá¡áá²áá»á¬ážá០ááœá²ááŒá¬ážáá¬ážáááºá
- áá±áá¬áá±á·á ẠááœáŸá±á·ááŒá±á¬ááºážááŒááºážááẠáááºá á¡ááºááºáá®áá±ážááŸááºážá ááœáŸáá·áºáááºááŸá¯ááŸáá·áºá¡áá° ááŒá áºáá±á«áºáá¬áááºá ááá¯ááá¯áááºááŸá¬á áááºá á¡áá¯á¶ážáá»ááŸá¯ áá¯ááºáááºážá ááºááẠááá¯ážááŸááºážáá«áááºá
áá±áá¬áá±á·á áºááŒá¿áá¬áá»á¬ážááá¯ááŒá±ááŸááºážááŒááºážá
áá±á¬ááºážáá«ážááá±á¬ááºá¡ááá¯ááºážááœááºá áá±áá¬áá±á·á áºááŒá±á¬ááºážáá²ááŸá¯áá»á¬ážá¡ááœáẠáá»ááºážáááºááŸá¯ááŸá áºáá¯ááᯠáá»áœááºá¯ááºááá¯á·á¡á¬áá¯á¶á áá¯ááºáá«áááºá
- áá±á¬ááºááŒááºáááá¯ááºááá¯ááºááŸá¯
- áá±á¬ááºááŒááºááá¯ááºáááºááŸá¯
ááá¬áááŒáá¯áááºááŒááºáááºááŸá¯áááŸááá² áá¯á¶ážáá ááºáááºáá¬ážááŒááºážáááŸáááá·áº ááŒáá·áºáá»ááºááŸá¯ááᯠáá¯á¶ážáááá¯ááºááá·áºááŒá±á¬ááºáž ááááá±ážáá»ááºáá áºáá¯á¡ááŒá Ạááá·áºááœááºážá ááºážá á¬ážáá«áááºá áá¯ááááá áºáá¯ááẠá¡áá»áááºáááœá²áá² ááŒáá·áºáá»ááºáá¯ááºáá±á¬ááºááá¯ááºáá¯á¶ááŸáá·áº áá áºáá»áááºáááºážááœáẠáá±á¬ááºááŒááºááá¯ááºáááºááŸá¯ááᯠááááºážááááºážáá¬ážááá¯ááºá á±áááºá¡ááœáẠá¡ááŒá±áá áºáá¯áá±ážáá«áááºá
áá»áœááºá¯ááºááá¯á·áá¯ááºáá±á¬ááºááá·áº ááá±á¬áá»ááºááẠááá¯ážááŸááºážáá±á¬ Spring Boot Flyway á¡ááºááá®áá±ážááŸááºážáá
áºáá¯ááŒá
áºáááºá Person
Ñ first_name
О last_name
áá±áá¬áá±á·á
áºáá²ááŸá¬ (á¡áá®ážá
ááºáá¯á¶áž áá¬áá¬ááŒááº- Person
á
á¬ážááœá²ááŸáá·áº f ááŒá
áºááirst_name
О last_name
- áá«ááœá±á áááºááœááºážááœá±áá«á) á¡áááºááŒá±á¬ááºážáá»ááºáá«áááºá last_name
в surname
.
áá°ááá»ááº
á¡áá±ážá áááºá¡áá»ááºá¡áááºáá»á¬ážááᯠááá±á·áá¬áá®á áá»áœááºá¯ááºááá¯á·á á¡áá¯á¶ážáá»áááá¯ááááºáá»á¬ážááŸáá·áºáááºáááºá áá»áœááºá¯ááºááá¯á·ááŒá¯áá¯ááºááẠááá¯á¡ááºáá±á¬ áá°ááá»ááºá¡áá»áá¯á·ááŸááá«áááºá áá»áœááºá¯ááºááá¯á·áááŸáááá¯áá±á¬ á¡áááááááºááẠááá¯ážááŸááºážáá±á¬ áá¯ááºáááºážá ááºáá áºáá¯ááŒá áºáááºá
ááŸááºá á¯á á á®ážááœá¬ážáá±ážááá¯ááºáᬠá¡ááŒá¶ááŒá¯áá»ááºá ááá¯ážááŸááºážáá±á¬ áá¯ááºáááºážá ááºáá»á¬ážááẠááá·áºá¡á¬áž áá¶á·ááá¯ážáá°áá®ááŸá¯ááœáẠááœá±áá»á¬ážá áœá¬ áááºáá¬á á±ááá¯ááºááẠ(ááá·áºáá¯áá¹ááá®á¡ááœáẠá¡áá¯ááºáá¯ááºáá±ážáá° áá»á¬ážááŒá¬ážáá±á áááºááœá± áá»á¬ážáá»á¬áž á á¯áá±á¬ááºážááá¯ááºáá±)á
áá±áá¬áá±á·á áºááá¯ááŒááºááŸááºáááºáááá¯á¡ááºáá«á
áááºážááẠá¡áá¯á¶ážáá»ááŒááºážáá¯ááºáááºážá ááºááᯠááá¯ážááŸááºážá á±ááẠ(á¡áá»áá¯á·áá±á¬áá±áá¬áá±á·á áºáá±á¬ááºááŒááºáá¯ááºááŒááºážáá»á¬ážááẠáááŒá áºááá¯ááºááá±á¬ááºáá®ážáá«ážááŒá áºáááºá áá»ááºááŒááºáž ááŸááºááŒááºážáá²á·ááá¯á·)á áá»áœááºá¯ááºááá¯á·ááẠá¡ááá®áá±ážááŸááºážáá»á¬ážááá¯áᬠááŒááºááœáá·áºááá¯áá«áááºá á€áááºážá¡á¬ážááŒáá·áº ááá·áºááœáẠááá°áá®áá±á¬ áá±áá¬áá±á·á áºáá»á¬áž (á¥ááá¬á SQL ááŸáá·áº NoSQL) ááŸááá»áŸááºááẠáááºá ááŒáá·áºáá»ááºááŸá¯ááá¯ááºááá¯ááºážááẠáá°áá®áá±áááºááŒá áºáááºá
á¡ááá®áá±ážááŸááºážááᯠáá¬ážááŸááºážáá áºáá¯ááá¯á· ááŒááºááŸáá·áºááẠá¡ááŒá²áááºáž ááŒá áºááá¯ááºáááẠ(áá±á¬ááºáááẠáááŸááá«)
ááá¯á¡ááºááá·áºá¡áá«ááŸáᬠááŒááºááŸáá·áºááá·áºáááºá áááºááŸááá¬ážááŸááºážááœáẠáá»áœááºááœááºážáá»ááºáá áºáá¯ááŸááá±áá«áá áá»áœááºá¯ááºááá¯á·ááẠáá±á¬ááºáá¯á¶ážááœááºá¡áá¯ááºáá¯ááºááá·áºáá¬ážááŸááºážááá¯á· ááŒááºááœá¬ážááá¯ááºáá«áááºá á€áá±á¬ááºáá¯á¶ážááœááºá¡áá¯ááºáá¯ááºáá¬ážááŸááºážáááºááááºáá¬ážááŸááºážááŒá áºáááºáá¯áá»áœááºá¯ááºááá¯á·áá°ááááºá áá áºáá¯áááºááá¯áá±á¬ áá¯ááºááŸáá·áº áá±áá¬áá±á·á Ạááá¯ááºáááºáá®ááŸá¯ááᯠááááºážááááºážááŒááºážááẠá¡ááœááºáááºáá²ááŒá®áž á á»á±ážááŒá®ážáá«áááºá
ááŸááºáá»ááº. ááá¯ááá¯áááºááŸá¯ááá¯ááºá á±áááºá¡ááœááºá á€áá±á¬ááºážáá«ážááœáẠá¡ááá®áá±ážááŸááºážá á¡ááááá¬ážááŸááºážááᯠááŒá±á¬ááºážáá²áá«áááºá
á¡ááá·áº 1- áááŠážá¡ááŒá±á¡áá±
App áá¬ážááŸááºáž: 1.0.0
DB áá¬ážááŸááºáž- v1
ááŸááºáá»ááº
áááºážááẠáá»áŸá±á¬ááºááœáŸá¬á áááŠážá¡ááŒá±á¡áá±ááŒá áºáááá·áºáááºá
áá±áá¬áá±á·á áºááŒá±á¬ááºážáá²ááŸá¯áá»á¬áž
DB áá«ááŸááááºá last_name.
CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);
insert into PERSON (first_name, last_name) values ('Dave', 'Syer');
áá¯ááºá¡ááŒá±á¬ááºážá¡áá²áá»á¬áž
á¡ááá®áá±ážááŸááºážááẠáá¯áá¹ááá¯ááºááá¯ááºáᬠá¡áá»ááºá¡áááºáá»á¬ážááᯠááááºážáááºážáá¬ážáááºá last_name
:
/*
* Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.flyway;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String lastName;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastname) {
this.lastName = lastname;
}
@Override
public String toString() {
return "Person [firstName=" + this.firstName + ", lastName=" + this.lastName
+ "]";
}
}
áá±á¬ááºááá¯á·ááœá²ááááá±á¬áá±á¬áºáá¶á¡áááºááŒá±á¬ááºážááŒááºážá
áá±á¬áºáá¶á¡áááºááᯠááŒá±á¬ááºážáá²áá¯á¶ ááá°áá¬ááᯠááŒáá·áºááŒáá«á áá¯á·á
á¡á¬áá¯á¶á áá¯ááºá á¡á±á¬ááºáá«á¥ááá¬ááẠá¡áá¬áá»á¬ážááᯠáááºááœááºáá»ááºááŸáááŸá áá»áá¯ážáá»ááºáááºááŒá áºáááºá áá±áá¬áá±á·á Ạááá¯ááºáááºáá®ááŸá¯ ááŒá¿áá¬ááᯠááá¯ááºááŒááẠá€á¡áá¬ááᯠáá»áœááºá¯ááºááá¯á· ááŒááá«áááºá
App áá¬ážááŸááºáž: 2.0.0.BAD
DB áá¬ážááŸááºáž- v2bad
ááŸááºáá»ááº
áááºááŸáááŒá±á¬ááºážáá²ááŸá¯áá»á¬ážááẠáá»áœááºá¯ááºááá¯á·á¡á¬áž á á¶ááá°áá¬ááŸá áºáᯠ(á¡áá±á¬ááºážááŸáá·áº á¡áá áº) ááᯠáá áºááŒáá¯ááºáááºáá¯ááºáá±á¬ááºááẠááœáá·áºáááŒá¯áá«á ááá¯á·ááŒá±á¬áá·áºá áá¯á¶ážáá ááºáááºááœá¬ážááŒááºážááŸá¬ á¡á±á¬ááºááŒááºááẠáááºáá²áááá·áºááẠ(áá°ááá»ááºáá»á¬ážááᯠááá·áºááœááºážá ááºážá á¬ážáá«áá áááºážááẠá¡ááŸááºáááẠáááŒá áºááá¯ááºáá«)á
A/B á ááºážáááºááŒááºážá
áááºááŸáá¡ááŒá±á¡áá±ááŸá¬ áá»áœááºá¯ááºááá¯á·ááœáẠá¡ááºááá®áá±ážááŸááºážáá¬ážááŸááºážáá
áºáá¯ááŸááááºá 1.0.0,
áá¯ááºáá¯ááºááŸá¯ááŸáá·áº áá±áá¬áá±á·á
áºááœáẠááŒáá·áºáá»ááºáá¬ážáááºá v1
. áá»áœááºá¯ááºááá¯á·ááẠá¡ááá®áá±ážááŸááºážá áá¯áááá¥ááá¬á áá¬ážááŸááºážááᯠá¡áá¯á¶ážááŒá¯ááẠááá¯á¡ááºáááºá 2.0.0.BAD
ááŸáá·áº áá±áá¬áá±á·á
áºááᯠá¡ááºááááºáá¯ááºáá«á v2bad
.
á¡ááá·áºáá»á¬áž
- áá¬ážááŸááºážá¡ááá®áá±ážááŸááºážáá¥ááá¬á¡áá
áºáá
áºáá¯ááᯠá¡áá¯á¶ážááŒá¯áá¬ážáááºá
2.0.0.BAD
áá±áá¬áá±á·á áºááᯠá¡ááºááááºáá¯ááºáááºáv2bad
- á¡ááá¯áá«áá±áá¬áá±á·á
ááááºá
v2bad
áá±á¬áºáá¶last_name
áááŸááá±á¬á·áá°áž - á¡á²áá«ááᯠááŒá±á¬ááºážááá¯ááºáááºásurname
- áá±áá¬áá±á·á
áºááŸáá·áº á¡ááá®áá±ážááŸááºáž á¡ááºááááºááẠá¡á±á¬ááºááŒááºáá²á·ááŒá®áž á¡áá»áá¯á·áá±á¬ áá¬áááá»á¬ážááᯠáá¯ááºáá±á¬ááºáá±áá«áááºá
1.0.0
, á¡ááŒá¬ážáá°áá»á¬áž - á¡ááœááº2.0.0.BAD
. á¡áá¬á¡á¬ážáá¯á¶ážááẠdatabase ááŸáá·áºáá»áááºáááºáá¬ážáááºáv2bad
- áá¬ážááŸááºážá¡á¬ážáá¯á¶ážáá¥ááá¬
1.0.0
áá±á¬áºáá¶áá²ááá¯á· áá±áá¬ááá·áºááœááºážááẠááŒáá¯ážá á¬ážáááºááŒá áºáá±á¬ááŒá±á¬áá·áº á¡ááŸá¬ážáá»á¬ážááᯠá áááºáá áºáá«áááºálast_name
áááŸááá±á¬á·áá°ážá - áá¬ážááŸááºážá¡á¬ážáá¯á¶ážáá¥ááá¬
2.0.0.BAD
ááŒá¿áá¬áááŸááá²á¡áá¯ááºáá¯ááºáá«áááá·áºáááºá
áááºááœá±á·ááŒááºáááá·áºá¡ááá¯ááºážá áá»áœááºá¯ááºááá¯á·ááẠáá±áá¬áá±á·á áºááŸáá·áº á¡ááá®áá±ážááŸááºážááá¯á· áá±á¬ááºááŒááºáááá¯ááºáááºáá±á¬ á¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááᯠááŒá¯áá¯ááºáá«á A/B á ááºážáááºááŒááºáž áááŒá áºááá¯ááºáá«á
áá»áŸá±á¬ááºááœáŸá¬ááᯠááŒááºááááºážáá«á
A/B deployment áá¯ááºááŒá®ážáá±á¬áẠáá°áááŒáá«á
áá¯á· (á¡áá®ážá
ááºáá¯á¶áž per.: á
á¬áá±ážáá°ááẠá€áá±áá¬ááœáẠA/B á
ááºážáááºááŒááºážááᯠááá¯ááá¯ááŒááºážááŒá
áºááá¯ááºáááºá) á¡ááá®áá±ážááŸááºážááᯠáá¬ážááŸááºážááá¯á· ááŒááºááŒá±á¬ááºážááẠáá¯á¶ážááŒááºáá²á·áááºá 1.0.0.
áá±áá¬áá±á·á
áºááᯠááŒááºáááááºážáá»ááºáá°ážááá¯áá«á
áá¯á·á
á¡ááá·áºáá»á¬áž
- áá»áœááºá¯ááºááá¯á·ááẠáá¬ážááŸááºážá¡ááá®áá±ážááŸááºážá¥ááá¬ááᯠáááºááá·áºááá¯ááºáááºá
2.0.0.BAD
- áá±áá¬áá±á·á
áºáá±áá²ááŒá
áºáááºá
v2bad
- áá¬ážááŸááºážááááºážá
1.0.0
á¡á²áá« áá¬áá²ááá¯áᬠáá¬ážááááºáá°ážásurname
á¡ááŸá¬ážá¡ááœááºážáá»á¬ážááœá±á·áááºá - ááá²áá»ááºááœá¬ážááŒá®á áá«ááá¯á· ááŒááºáááœá¬ážááá¯ááºáá±á¬á·áá°ážá
áááºááœá±á·ááŒááºáááá·áºá¡ááá¯ááºážá áá»áœááºá¯ááºááá¯á·ááẠáá±áá¬áá±á·á áºááŸáá·áº á¡ááá®áá±ážááŸááºážááá¯á· áá±á¬ááºááŒááºáááá¯ááºááá¯ááºáá±á¬ á¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááᯠááŒá¯áá¯ááºáá«áá áá»áœááºá¯ááºááá¯á·ááẠááááºáá¬ážááŸááºážááá¯á· ááŒááºááŸáá·áºááááá«á
Script áá¯ááºáá±á¬ááºááŸá¯ááŸááºáááºážáá»á¬áž
Backward incompatible scenario:
01) Run 1.0.0
02) Wait for the app (1.0.0) to boot
03) Generate a person by calling POST localhost:9991/person to version 1.0.0
04) Run 2.0.0.BAD
05) Wait for the app (2.0.0.BAD) to boot
06) Generate a person by calling POST localhost:9991/person to version 1.0.0 <-- this should fail
07) Generate a person by calling POST localhost:9992/person to version 2.0.0.BAD <-- this should pass
Starting app in version 1.0.0
Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:
{"firstName":"b73f639f-e176-4463-bf26-1135aace2f57","lastName":"b73f639f-e176-4463-bf26-1135aace2f57"}
Starting app in version 2.0.0.BAD
Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:
curl: (22) The requested URL returned error: 500 Internal Server Error
Generate a person in version 2.0.0.BAD
Sending a post to 127.0.0.1:9995/person. This is the response:
{"firstName":"e156be2e-06b6-4730-9c43-6e14cfcda125","surname":"e156be2e-06b6-4730-9c43-6e14cfcda125"}
áá±áá¬áá±á·á áºááŒá±á¬ááºážáá²ááŸá¯áá»á¬áž
á¡áááºááŒá±á¬ááºážáá±á¬ ááœáŸá±á·ááŒá±á¬ááºážááŒááºáž áá¬ááºááœáŸááºáž last_name
в surname
áááºážááŒá ẠFlyway áá¬ááºááœáŸááºáž-
CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);
insert into PERSON (first_name, last_name) values ('Dave', 'Syer');
á¡áááºááŒá±á¬ááºážáá±á¬ áá¬ááºááœáŸááºáž last_name
.
-- This change is backward incompatible - you can't do A/B testing
ALTER TABLE PERSON CHANGE last_name surname VARCHAR;
áá¯ááºá¡ááŒá±á¬ááºážá¡áá²áá»á¬áž
áá»áœááºá¯ááºááá¯á·ááẠáááºáááºá¡áááºááᯠááŒá±á¬ááºážáá²áá¬ážáááºá lastName
á¡áá±á«áº surname
.
áá±á¬áºáá¶áá áºáá¯á¡á¬áž áá±á¬ááºááŒááºááá¯ááºáááºáá±á¬áááºážááŒáá·áº á¡áááºááŒá±á¬ááºážááŒááºážá
áá«á áá»áœááºáá±á¬áºááá¯á· ááŒá¯á¶ááœá±á·ááá²á· á¡ááŒá áºá¡áá»á¬ážáá¯á¶áž á¡ááŒá±á¡áá±áá«á áá»áœááºá¯ááºááá¯á·ááẠáá±á¬ááºááŒááºáááá¯ááºááá¯ááºáá±á¬ á¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááᯠááŒá¯áá¯ááºááẠááá¯á¡ááºáá«áááºá áá¯á¶ážáá ááºáááºáá»ááẠááŒáá·áºáá»ááºááŒááºážá¡ááœááºá áá±á¬ááºáááºá¡ááá·áºáá»á¬ážááá«áá² áá±áá¬áá±á·á áºááŒá±á¬ááºážááœáŸá±á·ááŒááºážááᯠááá¯ážááá¯ážááŸááºážááŸááºáž ááá»áá·áºáá¯á¶ážááá·áºááŒá±á¬ááºáž áá»áœááºá¯ááºááá¯á· áááºáá±ááŒáá²á·ááŒá®ážááŒá áºáááºá áá±á¬ááºážáá«ážá á€á¡ááá¯ááºážááœááºá áá±á¬ááºááŒááºááá¯ááºáááºááŸá¯ááᯠááááºážááááºážáá¬ážá áẠááá¯áá»ááºáá±á¬ááááºááá¯áááŸáááẠáá±áá¬áá±á·á áºááŒá±á¬ááºážááœáŸá±á·ááŸá¯áá»á¬ážááŸáá·áºá¡áá° á¡ááá®áá±ážááŸááºáž á áá¯ááᯠááŒáá·áºáá»ááºáá¯ááºáá±á¬ááºáá«áááºá
ááŸááºá á¯á áá»áœááºá¯ááºááá¯á·ááœáẠáá¬ážááŸááºážáá±áá¬áá±á·á áºáá áºáá¯ááŸááááºááᯠáááááá«á
v1
. áááºážááœáẠáá±á¬áºáá¶áá»á¬áž áá«ááŸááááºáfirst_name
Оlast_name
. ááŒá±á¬ááºážáá²ááááºálast_name
á¡áá±á«áºsurname
. áá»áœááºá¯ááºááá¯á·ááœááºá¡ááºááºáá¬ážááŸááºážáááºážááŸááááºá1.0.0,
á¡áá¯á¶ážáááŒá¯ááá±ážáá±á¬surname
.
á¡ááá·áº 2: áá»áá¯ážááá¯ážá¡áááºááá·áºáá«á
App áá¬ážááŸááºáž: 2.0.0
DB áá¬ážááŸááºáž- v2
ááŸááºáá»ááº
áá±á¬áºáá¶á¡áá áºáá áºáá¯ááá·áºáᬠáááºážáá¡ááŒá±á¬ááºážá¡áá¬áá»á¬ážááᯠáá°ážáá°ááŒááºážááŒáá·áºá áá»áœááºá¯ááºááá¯á·ááẠáá±á¬ááºááŒááºááá¯ááºáááºáá±á¬ áá±áá¬áá±á·á áºááŒá±á¬ááºážáá²ááŸá¯áá»á¬ážááᯠáááºáá®ážáá±ážáá«áááºá áá áºáá»áááºáááºážááŸá¬áááºá áá»áœááºá¯ááºááá¯á·ááẠJAR ááᯠááŒááºááŸáá·áºááŒááºáž ááá¯á·ááá¯áẠJAR áá±á¬ááºážáá áºáᯠáá¯ááºáá±á¬ááºáá±áá«áá ááœááºáá»ááºá ááºá¡ááœááºáž áááºážááẠáá»ááºááœá¬ážáááºááá¯ááºáá±á
áá»áœááºá¯ááºááá¯á·ááẠáá¬ážááŸááºážá¡áá áºááᯠááŒáá·áºáá»ááá±ážáá±áááºá
á¡ááá·áºáá»á¬áž
- áá±á¬áºáá¶á¡áá
áºáá
áºáá¯áááºáá®ážááẠáá±áá¬áá±á·á
ẠááœáŸá±á·ááŒá±á¬ááºážááŒááºážááᯠáá¯ááºáá±á¬ááºáá«á
surname
. ááᯠáááºá DB áá¬ážááŸááºážv2
- áá±áá¬ááŸáá°ážáá°
last_name
вsurname
. áá»á±ážáá°ážááŒá¯. áááááŒá¯áá«ááá·áºááœáẠá€áá±áá¬áá»á¬ážá áœá¬ááŸááá«áá batch migration ááᯠáááºá ááºážá á¬ážááá·áºáááºá - á¡áá¯á¶ážááŒá¯áá²á· code ááá¯áá±ážáá«á ááŸá
áºáá¯áá¯á¶áž О МПвÑйááŸáá·áº á¡áá±á¬ááºážááᯠáá±á¬áºáá¶á ááᯠááá·áºá¡ááºááºáá¬ážááŸááºáž
2.0.0
- áá±á¬áºáá¶ááŸáááºááá¯ážááá¯áááºáá«á
surname
ááá¯ááºáááºánull
ááá¯á·ááá¯áẠl áá¶ááŸast_name
á¡áááºá ásurname
ááááºááŸááºáá¬ážáá«á áá»ááºááá¯á·ááááºágetLastName()
áá¯ááºá០ááœááºáááºááŒá áºáá±á¬ááŒá±á¬áá·áºánull
ááá·áºáá»áŸá±á¬ááºááœáŸá¬ááᯠááŒááºááŸáá·áºááá·áºá¡áá«3.0.0
ááá¯á·2.0.0
.
Spring Boot Flyway ááᯠáááºá¡áá¯á¶ážááŒá¯áá±áá«áá áá¬ážááŸááºážá
áááºáá»áááºááœáẠá€á¡ááá·áºááŸá
áºááá·áºááᯠáá¯ááºáá±á¬ááºáááºááŒá
áºáá«áááºá 2.0.0
áá»áŸá±á¬ááºááœáŸá¬áá»á¬ážá á¡áááºá áááºááẠáá±áá¬áá±á·á
áºáá¬ážááŸááºážáááºááŒááºážáá°ážááºááᯠááá¯ááºááá¯ááºáá¯ááºáá±á¬ááºáá«áá áááºážááá¯áá¯ááºáá±á¬ááºááẠááá°áá®ááá·áºá¡áá¬ááŸá
áºáá¯ááᯠáá¯ááºáá±á¬ááºááá«ááẠ(ááá db áá¬ážááŸááºážááᯠááá¯ááºááá¯ááºááœááºážáá¶ááŒá®áž á¡ááá®áá±ážááŸááºážá¡áá
áºááᯠá¡áá¯á¶ážááŒá¯áá«)á
á¡áá±ážááŒá®ážáááºá á¡áá áºáááºáá®ážáá¬ážáá±á¬áá±á¬áºáá¶ááá¯áááááá«á áááŒá áºááá·áºáá«á ááŒá ẠNULL ááá¯ááºáá«áá°áž. á¡áááºá áááºááẠrollback ááŒá¯áá¯ááºáá«áá á¡ááá®áá±ážááŸááºážáá±á¬ááºážááẠáá±á¬áºáá¶á¡áá áºá¡ááŒá±á¬ááºáž ááááá² áááºážááᯠááá·áºááœááºážá ááºá¡ááœááºáž ááá·áºááœááºážáááºááá¯ááºáá«á
Insert.
áá«áá±ááá·áº áá®ááá·áºáááºáá»ááºááᯠáá±á«ááºážááá·áºááẠááá·áº db ááŒá áºááœá¬ážáá«áááá·áºáááºáv2
á áááºážááẠáá±á¬áºáá¶á¡áá áºá áááºááá¯ážááᯠáááºááŸááºááẠááá¯á¡ááºáááºááŒá áºáááºá ááá·áºáááºáá»ááºáá»á¬ážááᯠáá»áá¯ážáá±á¬ááºááŒááºážáá®ááá¯á· áŠážáááºááœá¬ážáááºááŒá áºáááºáá¡áá±ážááŒá®ážáááºá áááºážáááºážááᯠáááºááŸá¬ážááá·áºáá«áááºá
getLastName()
áá¬ážááŸááºážáá²ááŸá¬ááá¯áá±á¬á·3.0.0
áá¯ááºááœáẠáá±á¬áºáá¶áá áºáá¯á ááá±á¬ááá¬ážáááŸááá«álast_name
. ááá¯ááá¯áá¬á null ááá¯á· áááºááŸááºáááºá áááºážáááºážááᯠáá»ááºáá¬ážáá²á·ááá¯ááºááŒá®áž á á áºáá±ážááŸá¯áá»á¬ážááᯠáá±á«ááºážááá·áºááá¯ááºáá«áááºánull
áá«áá±ááá·áº áá¯áá¹áááá±áááŸá¬ áá±áá»á¬á¡á±á¬ááºáá¯ááºááá¯á·á ááá¯áá±á¬ááºážáá²á· á¡ááŒá±áá áºáá¯áá«ágetSurname()
ááŸááºáááºáá±á¬ áá¯áááá¯ááºáá±á¬ áááºááá¯ážááᯠáááºááœá±ážáá»ááºáá²á·áááºá
A/B á ááºážáááºááŒááºážá
áááºááŸáá¡ááŒá±á¡áá±ááŸá¬ áá»áœááºá¯ááºááá¯á·ááœáẠá¡ááºááá®áá±ážááŸááºážáá¬ážááŸááºážáá
áºáá¯ááŸááááºá 1.0.0
á áá¯ááºáá¯ááºááŸá¯ááœáẠááŒáá·áºáá»ááºáá¬ážááŒá®áž áá±áá¬áá±á·á
áºá¡ááœáẠv1
. áá¬ážááŸááºážá¡ááá®áá±ážááŸááºážá áá¯áááá¥ááá¬ááᯠá¡áá¯á¶ážááŒá¯ááẠááá¯á¡ááºáááºá 2.0.0
áá±áá¬áá±á·á
áºááᯠupdate áá¯ááºáá«áááá·áºáááºá v2
.
á¡ááá·áºáá»á¬áž
- áá¬ážááŸááºážá¡ááá®áá±ážááŸááºážáá¥ááá¬á¡áá
áºáá
áºáá¯ááᯠá¡áá¯á¶ážááŒá¯áá¬ážáááºá
2.0.0
áá±áá¬áá±á·á áºááᯠá¡ááºááááºáá¯ááºáááºáv2
- á€á¡áá±á¬á¡ááœááºáž á¡áá»áá¯á·áá±á¬áá±á¬ááºážááá¯ááŸá¯áá»á¬ážááᯠáá¬ážááŸááºážááŒá
áºáááºáá»á¬ážááŒáá·áº áá¯ááºáá±á¬ááºáá²á·áááºá
1.0.0
- á¡ááºááááºááẠá¡á±á¬ááºááŒááºáá²á·ááŒá®áž ááá·áºááœáẠáá¬ážááŸááºážá¡ááá®áá±ážááŸááºážá áá¯ááºáá±á¬ááºáá±ááŸá¯áá»á¬áž á¡áá»á¬ážá¡ááŒá¬ážááŸááááºá
1.0.0
ááŸáá·áº á¡ááŒá¬ážáá¬ážááŸááºážáá»á¬áž2.0.0.
áá°ááá¯ááºážááẠdatabase ááŸáá·áº áááºááœááºáááºáv2
- áá¬ážááŸááºáž
1.0.0
áá±áá¬áá±á·á áºááœáẠáá»áá¯ážááá¯ážá¡áááºáá±á¬áºáá¶ááᯠá¡áá¯á¶ážáááŒá¯áá±á¬áºáááºáž áá¬ážááŸááºážááᯠá¡áá¯á¶ážááŒá¯áá¬ážáááºá2.0.0
á¡áá¯á¶ážááŒá¯áááºá á¡áá»ááºážáá»ááºáž á¡ááŸá±á¬áá·áºá¡ááŸááºáááŒá áºá á±áá² á¡ááŸá¬ážá¡ááœááºážáááŸáá á±ááá«á - áá¬ážááŸááºáž
2.0.0
áá±á¬áºáá¶á¡áá±á¬ááºážááŸáá·áº áá±á¬áºáá¶á¡áá áºááŸá áºáá¯á áá¯á¶ážááœáẠá¡áá»ááºá¡áááºáá»á¬ážááᯠááááºážáááºážáá¬ážááŒá®áž áá±á¬ááºááŒááºááá¯ááºáááºááŸá¯ááŸáá á±áá«áááºá
á¡áá±ážááŒá®ážáááºá ááá·áºááœáẠáá±á¬áºáá¶á¡áá±á¬ááºáž/á¡áá áºá០áááºááá¯ážáá»á¬ážááᯠá¡ááŒá±áá¶á áá±ááœááºááá·áºá¡áá¬áá»á¬ážááŸááá«áá ááᯠááá·áºááœáẠáááºáá°áááºááá¯ážáá»á¬ážááŸáááẠ(ááŒá áºááá¯ááºáá»á±áá»á¬ážáá±á¬á¡á¬ážááŒáá·áº áááºážááá¯á·ááẠááœáŸá±á·ááŒá±á¬ááºážáá±áá²ááŒá áºáááº) ááᯠááŸááºáá¬ážáá¬ážááá·áºáááºá á¥ááá¬á¡á¬ážááŒáá·áºá á á¬áá¯á¶ážááŒáá·áºá áááºáá²á·áá±á¬ áá±á¬ááºáá¯á¶ážá¡ááẠ(áááºááá·áºáá±á¬áºáá¶áá¯áá±á«áºáááºááŒá áºá á±) á¡áá¯á¶ážááŒá¯áá°á¡áá±á¡ááœááºááᯠáá±ááœááºááá¯áá«áá
A
ááá¯á·áá±á¬áẠáá±áá¬ááœáŸá±á·ááŒá±á¬ááºážááŒááºáž áááŒá®ážááá»ááºáž (old
ânew
áá±á¬áºáá¶) áá±á¬áºáá¶á¡áá áºáá áºáá¯ááᯠáááºáá±ážááŒááºážáá«á ááá·áºááœáẠáááá¯ááºáá®áá±á¬áá±áá¬ááŸáááá¯ááºáááºá
áá»áŸá±á¬ááºááœáŸá¬ááᯠááŒááºááááºážáá«á
ááᯠáá»áœááºá¯ááºááá¯á·ááœáẠá¡ááºááºáá¬ážááŸááºážááŸááááºá 2.0.0
ááŸáá·áº database áá²ááœáẠv2
.
á¡ááá·áºáá»á¬áž
- ááá·áºá¡ááá®áá±ážááŸááºážááᯠáá¬ážááŸááºážááá¯á· ááŒááºááŒá±á¬ááºážáá«á
1.0.0
. - áá¬ážááŸááºáž
1.0.0
áá±áá¬áá±á·á áºááœáẠáá±á¬áºáá¶ááᯠá¡áá¯á¶ážáááŒá¯áá«ásurname
ááá¯á·ááŒá±á¬áá·áº ááŒááºááŸáá·áºááŒááºážááẠá¡á±á¬ááºááŒááºááá·áºáááºá
DB á¡ááŒá±á¬ááºážá¡áá²áá»á¬áž
áá±áá¬áá±á·á
áºááœáẠá¡áááºááŸááá±á¬ áá±á¬áºáá¶áá
áºáᯠáá«ááŸááááºá last_name
.
Flyway á¡áááºážá¡ááŒá Ạáá¬ááºááœáŸááºáž-
CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);
insert into PERSON (first_name, last_name) values ('Dave', 'Syer');
áá¬ááºááœáŸááºážááá·áºáá«á surname
.
á¡á¬áá¯á¶á áá¯ááºá áááºááá·áºááœááºážáá±áá±á¬áá±á¬áºáá¶ááœáẠNOT NULL ááá·áºáááºáá»ááºáá»á¬ážááᯠáááºááá·áºáááááŒá±á¬ááºáž áááááá«á á¡áááºá áááºááẠJAR ááᯠááŒááºááŸáá·áºáá«áá áá¬ážááŸááºážáá±á¬ááºážááẠááá·áºááœááºážáá¬ážáá±á¬ áá±á¬áºáá¶á¡ááŒá±á¬ááºáž áááááá¯ááºáá² áááºážááᯠNULL ááá¯á· á¡ááá¯á¡áá»á±á¬áẠáááºááŸááºáá±ážáááºááŒá áºáááºá ááá¯ááá¯á·áá±á¬ááá·áºáááºáá»ááºáá»á¬ážááŸááá«áá á¡ááá®áá±ážááŸááºážáá±á¬ááºážáááºááá¯ážááŸááºážá áœá¬áá»ááºááŒá¬ážáááá·áºáááºá
-- NOTE: This field can't have the NOT NULL constraint cause if you rollback, the old version won't know about this field
-- and will always set it to NULL
ALTER TABLE PERSON ADD surname varchar(255);
-- WE'RE ASSUMING THAT IT'S A FAST MIGRATION - OTHERWISE WE WOULD HAVE TO MIGRATE IN BATCHES
UPDATE PERSON SET PERSON.surname = PERSON.last_name
áá¯ááºá¡ááŒá±á¬ááºážá¡áá²áá»á¬áž
áá»áœááºá¯ááºááá¯á·ááẠáá±áá¬á¡ááŒá
Ạááááºážáááºážáá¬ážáááºá last_name
ááŸááºá· surname
. áá
áºáá»áááºáááºážááŸá¬ááẠáá»áœááºá¯ááºááá¯á·áá¶á០áááºááááºá last_name
á€áá±á¬áºáá¶ááẠá¡áááºááá¯ááºáá¯á¶ážááŒá
áºáá±á¬ááŒá±á¬áá·áºá á¡áá¯á¶ážáá»ááŸá¯ áá¯ááºáááºážá
ááºá¡ááœááºážá á¡áá»áá¯á·áá±á¬ áá±á¬ááºážááá¯ááŸá¯áá»á¬ážááᯠááœááºážáá¶ááá±ážááá·áº á¡ááá®áá±ážááŸááºáž áá¬áááá
áºáá¯á áá¯ááºáá±á¬ááºááŒá®áž ááŒá
áºááá¯ááºáá«áááºá
/*
* Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.flyway;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String lastName;
private String surname;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* Reading from the new column if it's set. If not the from the old one.
*
* When migrating from version 1.0.0 -> 2.0.0 this can lead to a possibility that some data in
* the surname column is not up to date (during the migration process lastName could have been updated).
* In this case one can run yet another migration script after all applications have been deployed in the
* new version to ensure that the surname field is updated.
*
* However it makes sense since when looking at the migration from 2.0.0 -> 3.0.0. In 3.0.0 we no longer
* have a notion of lastName at all - so we don't update that column. If we rollback from 3.0.0 -> 2.0.0 if we
* would be reading from lastName, then we would have very old data (since not a single datum was inserted
* to lastName in version 3.0.0).
*/
public String getSurname() {
return this.surname != null ? this.surname : this.lastName;
}
/**
* Storing both FIRST_NAME and SURNAME entries
*/
public void setSurname(String surname) {
this.lastName = surname;
this.surname = surname;
}
@Override
public String toString() {
return "Person [firstName=" + this.firstName + ", lastName=" + this.lastName + ", surname=" + this.surname
+ "]";
}
}
á¡ááá·áº 3- áá¯ááºá០áá±á¬ááºáá¯á¶áž_á¡áááºááᯠáááºááŸá¬ážáá«á
App áá¬ážááŸááºáž: 3.0.0
DB áá¬ážááŸááºáž-v3
ááŸááºáá»ááº
ááŸááºáá»áẠper.- áá°áááºážáá±á¬ááºážáá«ážááœáẠá
á¬áá±ážáá°ááẠá¡ááá·áº 2 á០á€ááá±á¬ááºáá
á¬áá¬ážááᯠááŸá¬ážááœááºážá
áœá¬áá°ážáá°áááá«áááºá á€á¡ááá·áºááœááºá áá±á¬áºáá¶ááá¯á¡áá¯á¶ážááŒá¯ááá·áº áá¯ááºáá±á¬ááºááá¯ááºá
áœááºážááá¯áááºááŸá¬ážáááºá¡ááœáẠáááºááœááºáá±á¬ á¡ááá®áá±ážááŸááºážáá¯ááºááœáẠá¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááᯠááŒá¯áá¯ááºááá·áºáá«áááºá last_name
.
áá±á¬áºáá¶á¡áá áºáá áºáá¯ááá·áºáᬠáááºážáá¡ááŒá±á¬ááºážá¡áá¬áá»á¬ážááᯠáá°ážáá°ááŒááºážááŒáá·áºá áá»áœááºá¯ááºááá¯á·ááẠáá±á¬ááºááŒááºááœá²áááºá¡áá¯á¶ážááŒá¯ááá¯ááºáá±á¬ áá±áá¬áá±á·á áºááŒá±á¬ááºážáá²ááŸá¯áá»á¬ážááᯠáááºáá®ážáá²á·áááºá ááá¯á·á¡ááŒááºá áá»áœááºá¯ááºááá¯á·ááẠJAR ááᯠááŒááºááŸáá·áºááŒááºáž ááá¯á·ááá¯áẠJAR á¡áá±á¬ááºážáá áºáᯠáá¯ááºáá±á¬ááºáá±áá«áá áá¯ááºáá±á¬ááºáá±á ááºá¡ááœááºáž áááºážááẠáá»ááºááœá¬ážáááºááá¯ááºáá±á
áá»áŸá±á¬ááºááœáŸá¬ááᯠááŒááºááááºážáá«á
áá±á¬áá±á¬ááẠáá»áœááºáá±á¬áºááá¯á·ááŸá¬ á¡ááºááºáá¬ážááŸááºážááŸááá«áááºá 3.0.0
ááŸáá·áºáá±áá¬áá±á·á
v3
. áá¬ážááŸááºáž 3.0.0
áá±áá¬ááᯠáááááºážáááºážáá«áá°ážá last_name
. ááá¯ááá¯áá¬á á¡áá²ááŸá¬ surname
áá±á¬ááºáá¯á¶ážáá±á«áº á¡áá»ááºá¡áááºáá»á¬ážááᯠááááºážáááºážáá¬ážáááºá
á¡ááá·áºáá»á¬áž
- ááá·áºá¡ááá®áá±ážááŸááºážááᯠáá¬ážááŸááºážááá¯á· ááŒááºááŒá±á¬ááºážáá«á
2.0.0
. - áá¬ážááŸááºáž
2.0.0
ááŸáá·áºlast_name
Оsurname
. - áá¬ážááŸááºáž
2.0.0
áá°áááºásurname
áá¯áááá¯ááºáááºálast_name
áá±áá¬áá±á·á áºááŒá±á¬ááºážáá²ááŸá¯áá»á¬áž
áá±áá¬áá±á·á áºááœáẠááœá²á·á ááºážáá¯á¶ááá¯ááºáá¬ááŒá±á¬ááºážáá²ááŸá¯áá»á¬áž áááŸááá«á áá±áá¬á¡áá±á¬ááºážá áá±á¬ááºáá¯á¶ážááŒá±á¬ááºážááœáŸá±á·ááŒááºážááᯠáá¯ááºáá±á¬ááºááẠá¡á±á¬ááºáá« script ááᯠáá¯ááºáá±á¬ááºáááº-
-- WE'RE ASSUMING THAT IT'S A FAST MIGRATION - OTHERWISE WE WOULD HAVE TO MIGRATE IN BATCHES
-- ALSO WE'RE NOT CHECKING IF WE'RE NOT OVERRIDING EXISTING ENTRIES. WE WOULD HAVE TO COMPARE
-- ENTRY VERSIONS TO ENSURE THAT IF THERE IS ALREADY AN ENTRY WITH A HIGHER VERSION NUMBER
-- WE WILL NOT OVERRIDE IT.
UPDATE PERSON SET PERSON.surname = PERSON.last_name;
-- DROPPING THE NOT NULL CONSTRAINT; OTHERWISE YOU WILL TRY TO INSERT NULL VALUE OF THE LAST_NAME
-- WITH A NOT_NULL CONSTRAINT.
ALTER TABLE PERSON MODIFY COLUMN last_name varchar(255) NULL DEFAULT NULL;
áá¯ááºá¡ááŒá±á¬ááºážá¡áá²áá»á¬áž
ááŸááºáá»áẠper.- á€ááá±á¬ááºááá±á¬áºááŒáá»ááºááᯠá¡ááá·áº 2 á០á
á¬áá±ážáá°á ááŸá¬ážááœááºážá
áœá¬áá°ážáá°áá¬ážáá«áááºá áá±á¬ááºážáá«ážááá¯áá¹ááááŸáá·áºá¡áá®á á€á¡ááá·áºááŸá áá¯ááºá¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááẠáá±á¬áºáá¶ááŸáá·áºá¡áá¯ááºáá¯ááºáá±á¬ á¡á
áááºá¡ááá¯ááºážáá»á¬ážá០áááºááŸá¬ážááẠáááºááœááºááá·áºááẠlast_name
.
áá»áœááºá¯ááºááá¯á·ááẠáá±áá¬á¡ááŒá
Ạááááºážáááºážáá¬ážáááºá last_name
ááŸááºá· surname.
ááá¯á·á¡ááŒááºá áá±á¬áºáá¶ááŸáááºáááºá last_name
á¡áááºááá¯ááºáá¯á¶ážááá¯á·áá«á ááŒáá·áºáá»ááºááŒááºážáá¯ááºáááºážá
ááºá¡ááœááºážá á¡áá»áá¯á·áá±á¬áá±á¬ááºážááá¯ááŸá¯áá»á¬ážááᯠá¡ááá·áºááŒáŸáá·áºááœááºážáá¶ááá±ážááá·áº á¥ááá¬áá
áºáá¯ááŒáá·áº áá¯ááºáá±á¬ááºááá¯ááºáá«áááºá
/*
* Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.flyway;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String surname;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getSurname() {
return this.surname;
}
public void setSurname(String lastname) {
this.surname = lastname;
}
@Override
public String toString() {
return "Person [firstName=" + this.firstName + ", surname=" + this.surname
+ "]";
}
}
á¡ááá·áº 4: áá±áá¬áá±á·á áºááŸáá±á¬ááºáá¯á¶áž_á¡áááºááá¯áááºááŸá¬ážáá«á
App áá¬ážááŸááºáž: 4.0.0
DB áá¬ážááŸááºáž- v4
ááŸááºáá»ááº
áá¬ážááŸááºážáá¯ááºááŒá±á¬áá·áºáá«á 3.0.0
áá±á¬áºáá¶ááᯠááá¯á¶ážáá²á·áá«á last_name
áá±á¬ááºááŒááºáá¯ááºááœá¬ážáááºáá±á¬á· ááœááºáá»ááºá
ááºááŸá¬ áá¬á០ááá±á¬ááºážáá«áá°ážá 3.0.0
áá±áá¬áá±á·á
áºááŸáá±á¬áºáá¶ááá¯áááºááŸá¬ážááŒá®ážáá±á¬ááºá
Script áá¯ááºáá±á¬ááºááŸá¯ááŸááºáááºážáá»á¬áž
We will do it in the following way:
01) Run 1.0.0
02) Wait for the app (1.0.0) to boot
03) Generate a person by calling POST localhost:9991/person to version 1.0.0
04) Run 2.0.0
05) Wait for the app (2.0.0) to boot
06) Generate a person by calling POST localhost:9991/person to version 1.0.0
07) Generate a person by calling POST localhost:9992/person to version 2.0.0
08) Kill app (1.0.0)
09) Run 3.0.0
10) Wait for the app (3.0.0) to boot
11) Generate a person by calling POST localhost:9992/person to version 2.0.0
12) Generate a person by calling POST localhost:9993/person to version 3.0.0
13) Kill app (3.0.0)
14) Run 4.0.0
15) Wait for the app (4.0.0) to boot
16) Generate a person by calling POST localhost:9993/person to version 3.0.0
17) Generate a person by calling POST localhost:9994/person to version 4.0.0
Starting app in version 1.0.0
Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:
{"firstName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2","lastName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2"}
Starting app in version 2.0.0
Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:
{"firstName":"e41ee756-4fa7-4737-b832-e28827a00deb","lastName":"e41ee756-4fa7-4737-b832-e28827a00deb"}
Generate a person in version 2.0.0
Sending a post to 127.0.0.1:9992/person. This is the response:
{"firstName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","lastName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","surname":"0c1240f5-649a-4bc5-8aa9-cff855f3927f"}
Killing app 1.0.0
Starting app in version 3.0.0
Generate a person in version 2.0.0
Sending a post to 127.0.0.1:9992/person. This is the response:
{"firstName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","lastName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","surname":"74d84a9e-5f44-43b8-907c-148c6d26a71b"}
Generate a person in version 3.0.0
Sending a post to 127.0.0.1:9993/person. This is the response:
{"firstName":"c6564dbe-9ab5-40ae-9077-8ae6668d5862","surname":"c6564dbe-9ab5-40ae-9077-8ae6668d5862"}
Killing app 2.0.0
Starting app in version 4.0.0
Generate a person in version 3.0.0
Sending a post to 127.0.0.1:9993/person. This is the response:
{"firstName":"cbe942fc-832e-45e9-a838-0fae25c10a51","surname":"cbe942fc-832e-45e9-a838-0fae25c10a51"}
Generate a person in version 4.0.0
Sending a post to 127.0.0.1:9994/person. This is the response:
{"firstName":"ff6857ce-9c41-413a-863e-358e2719bf88","surname":"ff6857ce-9c41-413a-863e-358e2719bf88"}
DB á¡ááŒá±á¬ááºážá¡áá²áá»á¬áž
ááŸáá¯ááºážááŸááºáá« v3
áá±á¬áºáá¶ááᯠáááºááá¯ááºáá¯á¶áá«áá²á last_name
ááŸáá·áº áá»á±á¬ááºáá¯á¶ážáá±áá±á¬ ááá·áºáááºáá»ááºáá»á¬ážááᯠááá·áºáá«á
-- REMOVE THE COLUMN
ALTER TABLE PERSON DROP last_name;
-- ADD CONSTRAINTS
UPDATE PERSON SET surname='' WHERE surname IS NULL;
ALTER TABLE PERSON ALTER COLUMN surname VARCHAR NOT NULL;
áá¯ááºá¡ááŒá±á¬ááºážá¡áá²áá»á¬áž
áá¯ááºááŒá±á¬ááºážáá²ááŸá¯áááŸááá«á
áá±á¬ááºáá»ááº
áá±á¬ááºááŒááº-ááœá²áá¯á¶ážááá¯ááºáá±á¬ áá±á¬áºáá¶á¡áááºááŒá±á¬ááºážáá²ááŸá¯ááᯠáá»áœááºá¯ááºááá¯á· á¡á±á¬ááºááŒááºá áœá¬ á¡áá¯á¶ážáá»ááŒá®áž áá±á¬ááºááŒááº-ááá¯ááºáááºáá®áá±á¬ ááŒáá·áºáá»ááºááŸá¯áá»á¬ážá áœá¬ááᯠáá¯ááºáá±á¬ááºáá²á·áá«áááºá á¡á±á¬ááºááœáẠáá¯ááºáá±á¬ááºáá²á·áá±á¬ áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážá á¡áá»ááºážáá»á¯áẠááŒá áºáá«áááºá
- á¡ááá®áá±ážááŸááºážáá¬ážááŸááºážááᯠááŒáá·áºáá»ááºááŒááºážá
1.0.0
Ñv1
database schema (áá±á¬áºáá¶á¡ááẠ=last_name
) - á¡ááá®áá±ážááŸááºážáá¬ážááŸááºážááᯠááŒáá·áºáá»ááºááŒááºážá
2.0.0,
áá±áá¬ááᯠááááºážáááºážáá¬ážááá·áºá¡áá¬last_name
Оsurname
. áá»áŸá±á¬ááºááœáŸá¬ááá±áááºáááºálast_name
. áá±áá¬áá±á·á áºááẠáá¬ážááŸááºážááŒá áºáááºáv2
áá²á·ááá¯á·áá±á¬ áá±á¬áºáá¶áá»á¬áž áá«áááºáááºálast_name
ááŸáá·áºsurname. surname
l ááááá¹áá°ááŒá áºáá«áááºáast_name
. (ááŸááºáá»ááº- á€áá±á¬áºáá¶ááœáẠnot null ááá·áºáááºáá»ááºáááŸáááá«á - á¡ááá®áá±ážááŸááºážáá¬ážááŸááºážááᯠááŒáá·áºáá»ááºááŒááºážá
3.0.0
áá±áá¬áá»á¬ážááá¯áᬠááááºážáááºážáá±ážáááºásurname
áá»áá¯ážááá¯ážá¡áááºááŸáááºáááºá áá±áá¬áá±á·á áºá¡ááœááºá áá±á¬ááºáá¯á¶ážááŒá±á¬ááºážááœáŸá±á·ááŒááºážáá¯ááºáá±á¬ááºáá±áá«áááºálast_name
вsurname
. ááá·áºáááºáá»ááºáá áºáá¯áááºážááŒá áºáááºá NULL ááá¯ááºáá«áá°áž ááŸáááºááŸá¬ážáá²á·áááºálast_name
. áá±áá¬áá±á·á áºááẠááá¯áá¬ážááŸááºážááœáẠááŸááá±áá«ááŒá®áv3
- á¡ááá®áá±ážááŸááºážáá¬ážááŸááºážááᯠááŒáá·áºáá»ááºááŒááºážá
4.0.0
- áá¯ááºá¡ááœáẠá¡ááŒá±á¬ááºážá¡áá²áááŸááá«á áá±áá¬áá±á·á áºááŒáá·áºáá»ááºááŒááºážáv4
áááºááŸá¬ážáá±ážáá±á¬last_name
. á€áá±áá¬ááœáẠáááºááẠáá±áá¬áá±á·á áºááá¯á· áá»á±á¬ááºáá¯á¶ážáá±áá±á¬ ááá·áºáááºáá»ááºáá»á¬ážááᯠááá·áºááá¯ááºáááºá
á€áá»ááºážáááºááŸá¯ááᯠááá¯ááºáá¬ááŒááºážááŒáá·áºá áááºááẠáá±áá¬áá±á·á áº/á¡ááºááºáá®áá±ážááŸááºáž ááá¯ááºáááºáá®ááŸá¯ááᯠááá»áá¯ážáá»ááºáá² áá¬ážááŸááºážáá áºáá¯ááᯠá¡ááŒá²áááºáž ááŒááºááŸáá·áºááá¯ááºáááºá
áá¯ááº
á€áá±á¬ááºážáá«ážááœáẠá¡áá¯á¶ážááŒá¯áá¬ážáá±á¬ áá¯ááºá¡á¬ážáá¯á¶ážááᯠáááŸáááá¯ááºáá«ááŒá®á
á á®áá¶ááááºážáá»á¬áž
repository ááᯠclone áá¯ááºááŒá®ážáá±á¬ááºá á¡á±á¬ááºáá« folder structure ááá¯ááœá±á·ááá«áááºá
âââ boot-flyway-v1 - 1.0.0 version of the app with v1 of the schema
âââ boot-flyway-v2 - 2.0.0 version of the app with v2 of the schema (backward-compatible - app can be rolled back)
âââ boot-flyway-v2-bad - 2.0.0.BAD version of the app with v2bad of the schema (backward-incompatible - app cannot be rolled back)
âââ boot-flyway-v3 - 3.0.0 version of the app with v3 of the schema (app can be rolled back)
âââ boot-flyway-v4 - 4.0.0 version of the app with v4 of the schema (app can be rolled back)
áá¬ááºááœáŸááºáž
á¡á±á¬ááºáá±á¬áºááŒáá« scripts áá»á¬ážááœáẠáá±á¬áºááŒáá¬ážáá±á¬ script áá»á¬ážááᯠááẠrun ááá¯ááºááŒá®ážá áááºážááẠáá±áá¬áá±á·á áºááá¯á· áá±á¬ááºááŒááºááá¯ááºáááºááŒá®áž áááá¬ááááŒá áºáá±á¬ á¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááᯠááá¯ááºááŒáá«áááºá
ááŒááºá·ááẠáá±á¬ááºááŒááºááá¯ááºáááºáá²á· á¡ááŒá±á¬ááºážá¡áá²ááœá±áá²á· ááá á¹á á ááŒá±áž:
./scripts/scenario_backward_compatible.sh
ááŸáá·áºááœá±á·ááẠáá±á¬ááºááŒááºáááá¯ááºáááºáá²á· á¡ááŒá±á¬ááºážá¡áá²ááœá±áá²á· á¡ááŸá¯ááœá²á ááŒá±áž:
./scripts/scenario_backward_incompatible.sh
Spring Boot Sample Flyway
ááá°áá¬á¡á¬ážáá¯á¶ážááᯠáá°áááºá Spring Boot Sample Flyway.
ááŸá¬ááŒáá·áºááŸá¯ááá¯ááºáá«áááºá http://localhost:8080/flyway
script áá»á¬ážá
á¬áááºážááŸááá«áááºá
á€á¥ááá¬ááœáẠH2 ááœááºááá¯ážáẠ(at http://localhost:8080/h2-console
) ááá¯á·ááŒá±á¬áá·áº áááºááẠáá±áá¬áá±á·á
Ạá¡ááŒá±á¡áá±ááᯠááŒáá·áºááá¯ááºááẠ(áá°á jdbc URL ááŸá¬ ááŒá
áºáááºá jdbc:h2:mem:testdb
).
áá«á·á¡ááŒááº
áá±áá¬áá±á·á áºááŒááºáááºááŒááºáááºááŒááºážáá¯á¶á á¶áá»á¬áž á ááºáááºáááŒááºáá±ážááá¯á·
áá»áœááºá¯ááºááá¯á·áááá±á¬á·ááºááŸá á¡ááŒá¬ážáá±á¬ááºážáá«ážáá»á¬ážááá¯áááºáž áááºáá«-
Kubernetes- á áá áºá¡áááºážá¡ááŒá áºá á®áá¶ááá·áºááœá²ááŸá¯ááᯠá áááºáááºááŸááºááẠá¡áááºááŒá±á¬áá·áº á¡ááœááºá¡áá±ážááŒá®ážááááºážá Tekton ááá¯ááºááá¯ááºáž - Kubernetes-áá¬ááááá¯ááºááá¯ááºážáá»á¬áž Nginx á¡ááœáẠááŒá±á¬ááºážáá²áá±áá±á¬ áá±á¬áºáá»á°ážáá»á¬ážááᯠáááºáá±á¬ááºááŒááºážá Hashicorp áá±á¬ááºá á áºáááºá Kubernetes ááœáá·áºááŒá¯áá»ááºá¡á¬áž áááá«ááºáž ááœáá·áºááŒá¯áá»ááºáááŸááá² ClickHouse á០ClickHouse ááá¯á· ááŒá±á¬ááºážááœáŸá±á·ááŒááºážááẠáááºááá·áºá¡áá¬áá®ááá¯á· áŠážáááºááœá¬ážááááºážá Nginx áááºáá¬áá¬ááŒáá·áº Spring á¡ááºááºáá®áá±ážááŸááºážáá»á¬ážá Blue-Green ááŒáá·áºáá»ááºááŒááºážá
source: www.habr.com