рд╢реВрдиреНрдп рдбрд╛рдЙрдирдЯрд╛рдЗрдо рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕

рд╢реВрдиреНрдп рдбрд╛рдЙрдирдЯрд╛рдЗрдо рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕

рдпрд╣ рдЖрд▓реЗрдЦ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдореЗрдВ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕рдВрдЧрддрддрд╛ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рдХреИрд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПред рд╣рдо рдЖрдкрдХреЛ рдмрддрд╛рдПрдВрдЧреЗ рдХрд┐ рдпрджрд┐ рдЖрдк рдкреНрд░рд╛рд░рдВрднрд┐рдХ рддреИрдпрд╛рд░реА рдХреЗ рдмрд┐рдирд╛ рддреИрдирд╛рддреА рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдЖрдкрдХреЗ рдЙрддреНрдкрд╛рджрди рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХрд╛ рдХреНрдпрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдлрд┐рд░ рд╣рдо рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЬреАрд╡рдирдЪрдХреНрд░ рдХреЗ рдЙрди рдЪрд░рдгреЛрдВ рд╕реЗ рдЧреБрдЬрд░реЗрдВрдЧреЗ рдЬрд┐рдирдХреЗ рд▓рд┐рдП рд╢реВрдиреНрдп рдбрд╛рдЙрдирдЯрд╛рдЗрдо рдЖрд╡рд╢реНрдпрдХ рд╣реИ (рд▓рдЧрднрдЧред рд▓реЗрди: рдЖрдЧреЗ - рд╢реВрдиреНрдп рдбрд╛рдЙрдирдЯрд╛рдЗрдо). рд╣рдорд╛рд░реЗ рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдкрд╢реНрдЪрдЧрд╛рдореА-рдЕрд╕рдВрдЧрдд рдбреЗрдЯрд╛рдмреЗрд╕ рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдкрд╢реНрдЪрдЧрд╛рдореА-рд╕рдВрдЧрдд рддрд░реАрдХреЗ рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдпрджрд┐ рдЖрдк рд▓реЗрдЦ рд╕реЗ рдХреЛрдб рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЛ рд╕рдордЭрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЙрдиреНрд╣реЗрдВ рдпрд╣рд╛рдВ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ GitHub.

рдкрд░рд┐рдЪрдп

рд╢реВрдиреНрдп рдбрд╛рдЙрдирдЯрд╛рдЗрдо рдкрд░рд┐рдирд┐рдпреЛрдЬрди

рдХрд┐рддрдирд╛ рд░рд╣рд╕реНрдпрдордп рд╣реИ рд╢реВрдиреНрдп рдбрд╛рдЙрдирдЯрд╛рдЗрдо рдкрд░рд┐рдирд┐рдпреЛрдЬрди? рдЖрдк рдпрд╣ рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рддрдм рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдЖрдкрдХрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЗрд╕ рддрд░рд╣ рд╕реЗ рддреИрдирд╛рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдирдП рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдЙрддреНрдкрд╛рджрди рдореЗрдВ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкреЗрд╢ рдХрд░ рд╕рдХреЗрдВ, рдЬрдмрдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЗрд╕рдХреА рдЕрдиреБрдкрд▓рдмреНрдзрддрд╛ рдХрд╛ рдкрддрд╛ рдирд╣реАрдВ рдЪрд▓рддрд╛ рд╣реИред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдФрд░ рдХрдВрдкрдиреА рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ, рдпрд╣ рд╕рд░реНрд╡реЛрддреНрддрдо рд╕рдВрднрд╡ рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдкрд░рд┐рджреГрд╢реНрдп рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдирдИ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рдкреЗрд╢ рдХрд░рдиреЗ рдФрд░ рдмрдЧ рдХреЛ рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╡реНрдпрд╡рдзрд╛рди рдХреЗ рдареАрдХ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рдЗрд╕реЗ рдХреИрд╕реЗ рд╣рд╛рд╕рд┐рд▓ рдХрд░реЗрдВ? рдЗрд╕рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВ, рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ рдпрд╣рд╛рдВ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

  • рдЕрдкрдиреА рд╕реЗрд╡рд╛ рдХрд╛ рд╕рдВрд╕реНрдХрд░рдг рдХреНрд░рдорд╛рдВрдХ 1 рддреИрдирд╛рдд рдХрд░реЗрдВ
  • рдбреЗрдЯрд╛рдмреЗрд╕ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ
  • рдЕрдкрдиреА рд╕реЗрд╡рд╛ рдХреЗ рд╕рдВрд╕реНрдХрд░рдг #2 рдХреЛ рд╕рдВрд╕реНрдХрд░рдг #1 рдХреЗ рд╕рдорд╛рдирд╛рдВрддрд░ рддреИрдирд╛рдд рдХрд░реЗрдВ
  • рдЬреИрд╕реЗ рд╣реА рдЖрдк рджреЗрдЦреЗрдВ рдХрд┐ рд╕рдВрд╕реНрдХрд░рдг рдХреНрд░рдорд╛рдВрдХ 2 рдЙрд╕реА рддрд░рд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЬреИрд╕рд╛ рдЙрд╕реЗ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рд╕рдВрд╕реНрдХрд░рдг рдХреНрд░рдорд╛рдВрдХ 1 рдХреЛ рд╣рдЯрд╛ рджреЗрдВ
  • рддреИрдпрд╛рд░!

рдЖрд╕рд╛рди, рд╣реИ рдирд╛? рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдпрд╣ рдЗрддрдирд╛ рдЖрд╕рд╛рди рдирд╣реАрдВ рд╣реИ, рдФрд░ рд╣рдо рдмрд╛рдж рдореЗрдВ рдЗрд╕ рдкрд░ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗред рдЖрдЗрдП рдЕрдм рдПрдХ рдФрд░ рдХрд╛рдлреА рд╕рд╛рдорд╛рдиреНрдп рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВ - рдиреАрд▓рд╛ рд╣рд░рд╛ рдкрд░рд┐рдирд┐рдпреЛрдЬрдиред

рдХреНрдпрд╛ рддреБрдордиреЗ рдХрднреА рд╕реБрдирд╛ рд╣реИ рдиреАрд▓рд╛ рд╣рд░рд╛ рдкрд░рд┐рдирд┐рдпреЛрдЬрди? рдХреНрд▓рд╛рдЙрдб рдлрд╛рдЙрдВрдбреНрд░реА рдЗрд╕реЗ рдмреЗрд╣рдж рдЖрд╕рд╛рди рдмрдирд╛рддреА рд╣реИред рдмрд╕ рджреЗрдЦреЛ рдпрд╣ рд▓реЗрдЦ, рдЬрд╣рд╛рдВ рд╣рдо рдЗрд╕рдХрд╛ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВред рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдмрддрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рд╣рдо рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛рдПрдБ рдХрд┐ рдиреАрд▓рд╛ рд╣рд░рд╛ рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдХреИрд╕реЗ рдХрд░реЗрдВ:

  • рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдЖрдкрдХреЗ рдЙрддреНрдкрд╛рджрди рдХреЛрдб рдХреА рджреЛ рдкреНрд░рддрд┐рдпрд╛рдВ ("рдиреАрд▓реА" рдФрд░ "рд╣рд░реА") рдХрд╛рдо рдХрд░рддреА рд╣реИрдВ;
  • рд╕рднреА рдЯреНрд░реИрдлрд╝рд┐рдХ рдХреЛ рдиреАрд▓реЗ рд╡рд╛рддрд╛рд╡рд░рдг рдХреА рдУрд░ рдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░реЗрдВ, рдЕрд░реНрдерд╛рдд рддрд╛рдХрд┐ рдЙрддреНрдкрд╛рджрди рдпреВрдЖрд░рдПрд▓ рд╡рд╣реАрдВ рдЗрдВрдЧрд┐рдд рдХрд░реЗрдВ;
  • рд╣рд░рд┐рдд рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рд╕рднреА рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рддреИрдирд╛рдд рдХрд░рдирд╛ рдФрд░ рдЙрдирдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛;
  • рдпреВрдЖрд░рдПрд▓ рдХреЛ рдиреАрд▓реЗ рд╕реЗ рд╣рд░реЗ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдмрджрд▓реЗрдВ

рдмреНрд▓реВ рдЧреНрд░реАрди рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдПрдХ рдРрд╕рд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдЙрддреНрдкрд╛рджрди рдЯреВрдЯрдиреЗ рдХреА рдЪрд┐рдВрддрд╛ рдХрд┐рдП рдмрд┐рдирд╛ рдЖрд╕рд╛рдиреА рд╕реЗ рдирдИ рд╕реБрд╡рд┐рдзрд╛рдПрдБ рдкреЗрд╢ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрд╣ рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдЕрдЧрд░ рдХреБрдЫ рд╣реЛрддрд╛ рднреА рд╣реИ, рддреЛ рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ "рд╕реНрд╡рд┐рдЪ рдХреЛ рдлрд╝реНрд▓рд┐рдХ рдХрд░рдХреЗ" рдкрд┐рдЫрд▓реЗ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рд╡рд╛рдкрд╕ рдЖ рд╕рдХрддреЗ рд╣реИрдВред

рдЙрдкрд░реЛрдХреНрдд рд╕рднреА рдХреЛ рдкрдврд╝рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдк рдпрд╣ рдкреНрд░рд╢реНрди рдкреВрдЫ рд╕рдХрддреЗ рд╣реИрдВ: рд╢реВрдиреНрдп рдбрд╛рдЙрдирдЯрд╛рдЗрдо рдХрд╛ рдмреНрд▓реВ рдЧреНрд░реАрди рдкрд░рд┐рдирд┐рдпреЛрдЬрди рд╕реЗ рдХреНрдпрд╛ рд╕рдВрдмрдВрдз рд╣реИ?

рдЦреИрд░, рдЙрдирдореЗрдВ рдХрд╛рдлреА рд╕рдорд╛рдирддрд╛рдПрдВ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдПрдХ рд╣реА рд╡рд╛рддрд╛рд╡рд░рдг рдХреА рджреЛ рдкреНрд░рддрд┐рдпреЛрдВ рдХреЛ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рджреЛрдЧреБрдиреЗ рдкреНрд░рдпрд╛рд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдХреБрдЫ рдЯреАрдореЗрдВ рджрд╛рд╡рд╛ рдХрд░рддреА рд╣реИрдВ рдорд╛рд░реНрдЯрд┐рди рдлрд╛рдЙрд▓рд░, рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреА рдПрдХ рднрд┐рдиреНрдирддрд╛ рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдВ:

рдПрдХ рдЕрдиреНрдп рд╡рд┐рдХрд▓реНрдк рд╡реЗрдм рдФрд░ рдбреЛрдореЗрди рдкрд░рддреЛрдВ рдХреЗ рд▓рд┐рдП рдиреАрд▓реЗ-рд╣рд░реЗ рд╕реНрд╡рд┐рдЪ рдмрдирд╛рдХрд░ рдЙрд╕реА рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдореЗрдВ, рдбреЗрдЯрд╛рдмреЗрд╕ рдЕрдХреНрд╕рд░ рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЦрд╛рд╕рдХрд░ рдЬрдм рдЖрдкрдХреЛ рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рдХреЗ рдирдП рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХреА рд╕реНрдХреАрдорд╛ рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред

рдФрд░ рдпрд╣рд╛рдВ рд╣рдо рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛ рдкрд░ рдЖрддреЗ рд╣реИрдВред рдбреЗрдЯрд╛рдмреЗрд╕. рдЖрдЗрдП рдЗрд╕ рд╡рд╛рдХреНрдпрд╛рдВрд╢ рдкрд░ рдПрдХ рдФрд░ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред

рдбреЗрдЯрд╛рдмреЗрд╕ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ.

рдЕрдм рдЖрдкрдХреЛ рдЦреБрдж рд╕реЗ рд╕рд╡рд╛рд▓ рдкреВрдЫрдирд╛ рд╣реЛрдЧрд╛ - рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рдкрд░рд┐рд╡рд░реНрддрди рдкрд╢реНрдЪрдЧрд╛рдореА рд╕рдВрдЧрдд рдирд╣реАрдВ рд╣реИ? рдХреНрдпрд╛ рдРрдк рдХрд╛ рдореЗрд░рд╛ рдкрд╣рд▓рд╛ рд╕рдВрд╕реНрдХрд░рдг рдЯреВрдЯ рдирд╣реАрдВ рдЬрд╛рдПрдЧрд╛? рджрд░рдЕрд╕рд▓, рдпрд╣реА рд╣реЛрдЧрд╛...

рдЗрд╕рд▓рд┐рдП, рд╢реВрдиреНрдп рдбрд╛рдЙрдирдЯрд╛рдЗрдо/рдмреНрд▓реВ рдЧреНрд░реАрди рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдХреЗ рднрд╛рд░реА рд▓рд╛рднреЛрдВ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдХрдВрдкрдирд┐рдпрд╛рдВ рдЕрдкрдиреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЛ рддреИрдирд╛рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕реБрд░рдХреНрд╖рд┐рдд рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдкрд╛рд▓рди рдХрд░рддреА рд╣реИрдВ:

  • рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдирдП рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде рдПрдХ рдкреИрдХреЗрдЬ рддреИрдпрд╛рд░ рдХрд░реЗрдВ
  • рдЪрд▓ рд░рд╣реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдмрдВрдж рдХрд░реЗрдВ
  • рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдорд╛рдЗрдЧреНрд░реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЪрд▓рд╛рдПрдБ
  • рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рдПрдХ рдирдпрд╛ рд╕рдВрд╕реНрдХрд░рдг рддреИрдирд╛рдд рдФрд░ рд▓реЙрдиреНрдЪ рдХрд░реЗрдВ

рдЗрд╕ рдЖрд▓реЗрдЦ рдореЗрдВ, рд╣рдо рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдмрддрд╛рдПрдВрдЧреЗ рдХрд┐ рд╢реВрдиреНрдп рдбрд╛рдЙрдирдЯрд╛рдЗрдо рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдХрд╛ рд▓рд╛рдн рдЙрдард╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдк рдЕрдкрдиреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдФрд░ рдХреЛрдб рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдбреЗрдЯрд╛рдмреЗрд╕ рдХреА рд╕рдорд╕реНрдпрд╛рдПрдВ

рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рд╕реНрдЯреЗрдЯрд▓реЗрд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реИ рдЬреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдХреЛрдИ рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЖрдк рддреБрд░рдВрдд рд╢реВрдиреНрдп рдбрд╛рдЙрдирдЯрд╛рдЗрдо рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рдХреЛ рдбреЗрдЯрд╛ рдХреЛ рдХрд╣реАрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рд╕рд░реНрдХрд┐рдЯ рдореЗрдВ рдХреЛрдИ рднреА рдмрджрд▓рд╛рд╡ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рджреЛ рдмрд╛рд░ рд╕реЛрдЪрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╣рдо рд╕реНрдХреАрдорд╛ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд┐рд╡рд░рдг рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ рддрд╛рдХрд┐ рдиреЛ-рдбрд╛рдЙрдирдЯрд╛рдЗрдо рдкрд░рд┐рдирд┐рдпреЛрдЬрди рд╕рдВрднрд╡ рд╣реЛ, рдЖрдЗрдП рдкрд╣рд▓реЗ рд╡рд░реНрдЬрдирд┐рдВрдЧ рд╕реНрдХреАрдорд╛ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдВред

рд╕рдВрд╕реНрдХрд░рдг рдпреЛрдЬрдирд╛

рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рд╣рдо рдкреНрд░рдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ flyway рдПрдХ рд╕рдВрд╕реНрдХрд░рдг рдирд┐рдпрдВрддреНрд░рдг рдЙрдкрдХрд░рдг рдХреЗ рд░реВрдк рдореЗрдВ (рд▓рдЧрднрдЧред рдЕрдиреБрд╡рд╛рдж: рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ). рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ, рд╣рдо рдПрдХ рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рднреА рд▓рд┐рдЦреЗрдВрдЧреЗ рдЬрд┐рд╕рдореЗрдВ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдлреНрд▓рд╛рдИрд╡реЗ рд╕рдорд░реНрдерди рд╣реИ рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕рдВрджрд░реНрдн рд╕реЗрдЯ рдХрд░рддреЗ рд╕рдордп рд╕реНрдХреАрдорд╛ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдХрд░реЗрдЧрд╛ред рдлреНрд▓рд╛рдИрд╡реЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдЖрдк рдорд╛рдЗрдЧреНрд░реЗрд╢рди рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдЕрдкрдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ)ред classpath:db/migration). рдпрд╣рд╛рдВ рдЖрдк рдРрд╕реА рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ

тФФтФАтФА db
 тФФтФАтФА migration
     тФЬтФАтФА V1__init.sql
     тФЬтФАтФА V2__Add_surname.sql
     тФЬтФАтФА V3__Final_migration.sql
     тФФтФАтФА V4__Remove_lastname.sql

рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рд╣рдо 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 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЖрдкрдХреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдХреИрд╕реЗ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдФрд░ рдлреНрд▓рд╛рдИрд╡реЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП рджреЗрдЦреЗрдВ рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдбреЙрдХреНрд╕.

рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдХреЗ рд╕рд╛рде рд╕реНрд░реЛрдд рдирд┐рдпрдВрддреНрд░рдг рдЙрдкрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ, рдЖрдкрдХреЛ 2 рдмрдбрд╝реЗ рд▓рд╛рдн рдорд┐рд▓рддреЗ рд╣реИрдВ:

  • рдЖрдк рдбреЗрдЯрд╛рдмреЗрд╕ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рдХреЛрдб рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рд╕реЗ рдЕрд▓рдЧ рдХрд░рддреЗ рд╣реИрдВ
  • рдбреЗрдЯрд╛рдмреЗрд╕ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдЖрдкрдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд░реЛрд▓рдЖрдЙрдЯ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рд╣реЛрддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд рдЖрдкрдХреА рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕рд░рд▓ рд╣реЛ рдЧрдИ рд╣реИ

рдбреЗрдЯрд╛рдмреЗрд╕ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рдирд┐рд╡рд╛рд░рдг

рд▓реЗрдЦ рдХреЗ рдЕрдЧрд▓реЗ рднрд╛рдЧ рдореЗрдВ, рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рджреЛ рджреГрд╖реНрдЯрд┐рдХреЛрдгреЛрдВ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдВрдЧреЗред

  • рдкрд┐рдЫрдбрд╝реА рдЕрд╕рдВрдЧрддрд┐
  • рдкрд╢реНрдЪ рд╕рдВрдЧрддрддрд╛

рдкрд╣рд▓реЗ рд╡рд╛рд▓реЗ рдХреЛ рдПрдХ рдЪреЗрддрд╛рд╡рдиреА рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдирд╛ рдЬрд╛рдПрдЧрд╛ рдХрд┐ рдЖрдкрдХреЛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рддреИрдпрд╛рд░реА рдХреЗ рдмрд┐рдирд╛ рд╢реВрдиреНрдп рдбрд╛рдЙрдирдЯрд╛рдЗрдо рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП... рджреВрд╕рд░рд╛ рдЗрд╕ рдмрд╛рдд рдХрд╛ рд╕рдорд╛рдзрд╛рди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдбрд╛рдЙрдирдЯрд╛рдЗрдо рдХреЗ рдмрд┐рдирд╛ рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕рд╛рде рд╣реА рдмреИрдХрд╡рд░реНрдб рд╕рдВрдЧрддрддрд╛ рдмрдирд╛рдП рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВред

рд╣рдорд╛рд░рд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдЬрд┐рд╕ рдкрд░ рд╣рдо рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ рд╡рд╣ рдПрдХ рд╕рд░рд▓ рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдлреНрд▓рд╛рдИрд╡реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реЛрдЧрд╛ Person ╤Б first_name ╨╕ last_name рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ (рд▓рдЧрднрдЧред рдЕрдиреБрд╡рд╛рдж: Person рдПрдХ рдЯреЗрдмрд▓ рд╣реИ рдФрд░ рдПрдлirst_name ╨╕ last_name - рдпреЗ рдЗрд╕рдореЗрдВ рдлрд╝реАрд▓реНрдб рд╣реИрдВ). рд╣рдо рдирд╛рдо рдмрджрд▓рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ last_name ╨▓ surname.

рдорд╛рдиреНрдпрддрд╛рдУрдВ

рд╡рд┐рд╡рд░рдг рдореЗрдВ рдЬрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдЕрдкрдиреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдзрд╛рд░рдгрд╛рдПрдБ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдореБрдЦреНрдп рдкрд░рд┐рдгрд╛рдо рдЬреЛ рд╣рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рд╡рд╣ рдХрд╛рдлреА рд╕рд░рд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реЛрдЧреАред

рдиреЛрдЯред рдмрд┐рдЬрдиреЗрд╕ рдкреНрд░реЛ-рдЯрд┐рдкред рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рд╕реЗ рдЖрдк рд╕рдорд░реНрдерди рдкрд░ рдмрд╣реБрдд рд╕рд╛рд░рд╛ рдкреИрд╕рд╛ рдмрдЪрд╛ рд╕рдХрддреЗ рд╣реИрдВ (рдЬрд┐рддрдиреЗ рдЕрдзрд┐рдХ рд▓реЛрдЧ рдЖрдкрдХреА рдХрдВрдкрдиреА рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ, рдЙрддрдирд╛ рдЕрдзрд┐рдХ рдкреИрд╕рд╛ рдЖрдк рдмрдЪрд╛ рд╕рдХрддреЗ рд╣реИрдВ)!

рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рд░реЛрд▓рдмреИрдХ рдХрд░рдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ

рдпрд╣ рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рддрд╛ рд╣реИ (рдХреБрдЫ рдбреЗрдЯрд╛рдмреЗрд╕ рд░реЛрд▓рдмреИрдХ рд▓рдЧрднрдЧ рдЕрд╕рдВрднрд╡ рд╣реИрдВ, рдЬреИрд╕реЗ рд╡рд┐рд▓реЛрдкрди рд░реЛрд▓рдмреИрдХ)ред рд╣рдо рдХреЗрд╡рд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╡рд╛рдкрд╕ рд▓реЗрдирд╛ рдкрд╕рдВрдж рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рддрд░рд╣, рднрд▓реЗ рд╣реА рдЖрдкрдХреЗ рдкрд╛рд╕ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдбреЗрдЯрд╛рдмреЗрд╕ рд╣реЛрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, SQL рдФрд░ NoSQL), рдЖрдкрдХреА рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдПрдХ рдЬреИрд╕реА рджрд┐рдЦреЗрдЧреАред

рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдПрдХ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд╡рд╛рдкрд╕ рд░реЛрд▓ рдХрд░рдирд╛ рд╣рдореЗрд╢рд╛ рд╕рдВрднрд╡ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП (рдЕрдм рдФрд░ рдирд╣реАрдВ)

рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдиреЗ рдкрд░ рд╣реА рд░реЛрд▓рдмреИрдХ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рд╡рд░реНрддрдорд╛рди рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдХреЛрдИ рдмрдЧ рд╣реИ рдЬрд┐рд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ рдареАрдХ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рд╣рдореЗрдВ рдирд╡реАрдирддрдо рдХрд╛рд░реНрдпрд╢реАрд▓ рд╕рдВрд╕реНрдХрд░рдг рдкрд░ рд╡рд╛рдкрд╕ рд▓реМрдЯрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдирд╡реАрдирддрдо рдХрд╛рд░реНрдпрд╢реАрд▓ рд╕рдВрд╕реНрдХрд░рдг рдкрд┐рдЫрд▓рд╛ рд╕рдВрд╕реНрдХрд░рдг рд╣реИред рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рд░реЛрд▓рдЖрдЙрдЯ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕рдВрдЧрддрддрд╛ рдмрдирд╛рдП рд░рдЦрдирд╛ рдмреЗрд╣рдж рдХрдард┐рди рдФрд░ рдорд╣рдВрдЧрд╛ рд╣реЛрдЧрд╛ред

╨Ч╨░╨╝╨╡╤В╨║╨░. рдЕрдзрд┐рдХ рдкрдардиреАрдпрддрд╛ рдХреЗ рд▓рд┐рдП, рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рд╣рдо рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдкреНрд░рдореБрдЦ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдмрджрд▓ рджреЗрдВрдЧреЗред

рдЪрд░рдг 1: рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрд╡рд╕реНрдерд╛

рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╕рдВрд╕реНрдХрд░рдг: 1.0.0
рдбреАрдмреА рд╕рдВрд╕реНрдХрд░рдг: v1

рдЯрд┐рдкреНрдкрдгреА

рдпрд╣ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрдерд┐рддрд┐ рд╣реЛрдЧреА.

рдбреЗрдЯрд╛рдмреЗрд╕ рдкрд░рд┐рд╡рд░реНрддрди

рдбреАрдмреА рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИ 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
                + "]";
    }
}

рдкреАрдЫреЗ рдХреА рдУрд░ рдЕрд╕рдВрдЧрдд рдХреЙрд▓рдо рдХрд╛ рдирд╛рдо рдмрджрд▓рдирд╛

рдЖрдЗрдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВ рдХрд┐ рдХреЙрд▓рдо рдХрд╛ рдирд╛рдо рдХреИрд╕реЗ рдмрджрд▓рд╛ рдЬрд╛рдП:

рдЪреЗрддрд╛рд╡рдиреАред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рдЬрд╛рдирдмреВрдЭрдХрд░ рдЪреАрдЬрд╝реЛрдВ рдХреЛ рддреЛрдбрд╝ рджреЗрдЧрд╛ред рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рд╕рдВрдЧрддрддрд╛ рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рджрд┐рдЦрд╛рддреЗ рд╣реИрдВред

рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╕рдВрд╕реНрдХрд░рдг: 2.0.0.BAD

рдбреАрдмреА рд╕рдВрд╕реНрдХрд░рдг: v2bad

рдЯрд┐рдкреНрдкрдгреА

рд╡рд░реНрддрдорд╛рди рдкрд░рд┐рд╡рд░реНрддрди рд╣рдореЗрдВ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рджреЛ рдЙрджрд╛рд╣рд░рдг (рдкреБрд░рд╛рдиреЗ рдФрд░ рдирдП) рдЪрд▓рд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╢реВрдиреНрдп рдбрд╛рдЙрдирдЯрд╛рдЗрдо рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдХрдард┐рди рд╣реЛрдЧрд╛ (рдпрджрд┐ рдорд╛рдиреНрдпрддрд╛рдУрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдП, рддреЛ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрд╕рдВрднрд╡ рд╣реИ)ред

рдП/рдмреА рдкрд░реАрдХреНрд╖рдг

рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕рдВрд╕реНрдХрд░рдг рд╣реИ 1.0.0, рдЙрддреНрдкрд╛рджрди рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рддреИрдирд╛рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ v1. рд╣рдореЗрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рджреВрд╕рд░рд╛ рдЙрджрд╛рд╣рд░рдг, рд╕рдВрд╕реНрдХрд░рдг рддреИрдирд╛рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ 2.0.0.BAD, рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдЕрджреНрдпрддрди рдХрд░реЗрдВ v2bad.

рдХрджрдо:

  1. рд╕рдВрд╕реНрдХрд░рдг рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рдПрдХ рдирдпрд╛ рдЙрджрд╛рд╣рд░рдг рддреИрдирд╛рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ 2.0.0.BADрдЬреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддрд╛ рд╣реИ v2bad
  2. рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ v2bad рд╕реНрддрдВрдн last_name рдЕрдм рдЕрд╕реНрддрд┐рддреНрд╡ рдореЗрдВ рдирд╣реАрдВ рд╣реИ - рдЗрд╕реЗ рдмрджрд▓ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ surname
  3. рдбреЗрдЯрд╛рдмреЗрд╕ рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЕрджреНрдпрддрди рд╕рдлрд▓ рд░рд╣рд╛ рдФрд░ рдХреБрдЫ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдЪрд▓ рд░рд╣реЗ рд╣реИрдВ 1.0.0, рдЕрдиреНрдп - рдореЗрдВ 2.0.0.BAD. рд╕рдм рдХреБрдЫ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ v2bad
  4. рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рднреА рдЙрджрд╛рд╣рд░рдг 1.0.0 рддреНрд░реБрдЯрд┐рдпрд╛рдБ рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрдВрдЧреЗ рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдХреЙрд▓рдо рдореЗрдВ рдбреЗрдЯрд╛ рдбрд╛рд▓рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВрдЧреЗ last_nameрдЬреЛ рдЕрдм рдЕрд╕реНрддрд┐рддреНрд╡ рдореЗрдВ рдирд╣реАрдВ рд╣реИ
  5. рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рднреА рдЙрджрд╛рд╣рд░рдг 2.0.0.BAD рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╕рдорд╕реНрдпрд╛ рдХреЗ рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдпрджрд┐ рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдкреАрдЫреЗ рдХреА рдУрд░ рдЕрд╕рдВрдЧрдд рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдП/рдмреА рдкрд░реАрдХреНрд╖рдг рдЕрд╕рдВрднрд╡ рд╣реИред

рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд░реЛрд▓рдмреИрдХ

рдЖрдЗрдП рдорд╛рди рд▓реЗрдВ рдХрд┐ рдП/рдмреА рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж (рд▓рдЧрднрдЧред рдкреНрд░рддрд┐.: рд▓реЗрдЦрдХ рдХрд╛ рдЖрд╢рдп рд╢рд╛рдпрдж рдпрд╣рд╛рдВ рдП/рдмреА рдкрд░реАрдХреНрд╖рдг рд╕реЗ рд╣реИ) рд╣рдордиреЗ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдХрд┐ рд╣рдореЗрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд╡рд╛рдкрд╕ рд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ 1.0.0. рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рд░реЛрд▓рдмреИрдХ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рдХрджрдо:

  1. рд╣рдо рд╕рдВрд╕реНрдХрд░рдг рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдХреЛ рд░реЛрдХрддреЗ рд╣реИрдВ 2.0.0.BAD
  2. рдбреЗрдЯрд╛рдмреЗрд╕ рдЕрднреА рднреА рд╣реИ v2bad
  3. рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдмрд╛рдж рд╕реЗ 1.0.0 рд╕рдордЭ рдореЗрдВ рдирд╣реАрдВ рдЖрддрд╛ рдХрд┐ рдпрд╣ рдХреНрдпрд╛ рд╣реИ surname, рд╣рдо рддреНрд░реБрдЯрд┐рдпрд╛рдБ рджреЗрдЦреЗрдВрдЧреЗ
  4. рдирд░рдХ рдЯреВрдЯ рдЧрдпрд╛ рд╣реИ, рд╣рдо рдЕрдм рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддреЗ

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдпрджрд┐ рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдкреАрдЫреЗ рдХреА рдУрд░ рдЕрд╕рдВрдЧрдд рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдкрд┐рдЫрд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдЖ рд╕рдХрддреЗред

рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдирд┐рд╖реНрдкрд╛рджрди рд▓реЙрдЧ

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

рд╕реНрд░реЛрдд рдлреНрд▓рд╛рдИрд╡реЗ рд╕реНрдХреНрд░рд┐рдкреНрдЯ:

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.

рдХрд┐рд╕реА рдХреЙрд▓рдо рдХрд╛ рдирд╛рдо рдкрд╢реНрдЪ-рд╕рдВрдЧрдд рддрд░реАрдХреЗ рд╕реЗ рдмрджрд▓рдирд╛

рдпрд╣ рд╕рдмрд╕реЗ рдЖрдо рд╕реНрдерд┐рддрд┐ рд╣реИ рдЬрд┐рд╕рдХрд╛ рд╣рдо рд╕рд╛рдордирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдореЗрдВ рдкреАрдЫреЗ рдХреА рдУрд░ рдЕрд╕рдВрдЧрдд рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рдо рдкрд╣рд▓реЗ рд╣реА рд╕рд╛рдмрд┐рдд рдХрд░ рдЪреБрдХреЗ рд╣реИрдВ рдХрд┐ рд╢реВрдиреНрдп-рдбрд╛рдЙрдирдЯрд╛рдЗрдо рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рдЪрд░рдгреЛрдВ рдХреЗ рдмрд┐рдирд╛ рдХреЗрд╡рд▓ рдбреЗрдЯрд╛рдмреЗрд╕ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рд▓реЗрдЦ рдХреЗ рдЗрд╕ рднрд╛рдЧ рдореЗрдВ, рд╣рдо рдмреИрдХрд╡рд░реНрдб рд╕рдВрдЧрддрддрд╛ рдмрдирд╛рдП рд░рдЦрддреЗ рд╣реБрдП рд╡рд╛рдВрдЫрд┐рдд рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛рдмреЗрд╕ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдХреЗ рд╕рд╛рде рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА 3 рддреИрдирд╛рддреА рдХрд░реЗрдВрдЧреЗред

рдиреЛрдЯред рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕рдВрд╕реНрдХрд░рдг рдбреЗрдЯрд╛рдмреЗрд╕ рд╣реИ v1. рдЗрд╕рдореЗрдВ рдХреЙрд▓рдо рд╣реИрдВ first_name ╨╕ last_name. рд╣рдореЗрдВ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ last_name рдкрд░ surname. рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдРрдк рд╕рдВрд╕реНрдХрд░рдг рднреА рд╣реИ 1.0.0, рдЬрд┐рд╕рдХрд╛ рдЕрднреА рддрдХ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ surname.

рдЪрд░рдг 2: рдЙрдкрдирд╛рдо рдЬреЛрдбрд╝реЗрдВ

рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╕рдВрд╕реНрдХрд░рдг: 2.0.0
рдбреАрдмреА рд╕рдВрд╕реНрдХрд░рдг: v2

рдЯрд┐рдкреНрдкрдгреА

рдПрдХ рдирдпрд╛ рдХреЙрд▓рдо рдЬреЛрдбрд╝рдХрд░ рдФрд░ рдЙрд╕рдХреА рд╕рд╛рдордЧреНрд░реА рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдХрд░, рд╣рдо рдкрд╢реНрдЪрдЧрд╛рдореА рд╕рдВрдЧрдд рдбреЗрдЯрд╛рдмреЗрд╕ рдкрд░рд┐рд╡рд░реНрддрди рдмрдирд╛рддреЗ рд╣реИрдВред рдЙрд╕реА рд╕рдордп, рдпрджрд┐ рд╣рдо JAR рдХреЛ рд░реЛрд▓рдмреИрдХ рдХрд░рддреЗ рд╣реИрдВ рдпрд╛ рдкреБрд░рд╛рдирд╛ JAR рдЪрд╛рд▓реВ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди рдирд╣реАрдВ рдЯреВрдЯреЗрдЧрд╛ред

рд╣рдо рдПрдХ рдирдпрд╛ рд╕рдВрд╕реНрдХрд░рдг рд▓рд╛ рд░рд╣реЗ рд╣реИрдВ

рдХрджрдо:

  1. рдирдпрд╛ рдХреЙрд▓рдо рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛рдмреЗрд╕ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдХрд░реЗрдВ surname. рдЕрдм рдЖрдкрдХрд╛ DB рд╕рдВрд╕реНрдХрд░рдг v2
  2. рд╕реЗ рдбреЗрдЯрд╛ рдХреЙрдкреА рдХрд░реЗрдВ last_name ╨▓ surname. рдзреНрдпрд╛рди рджреЗрдВрдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдпрд╣ рдбреЗрдЯрд╛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдмреИрдЪ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП!
  3. рд╡рд╣ рдХреЛрдб рд▓рд┐рдЦреЗрдВ рдЬрд╣рд╛рдВ рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рджреЛрдиреЛрдВ ╨╕ рдирдпрд╛рдФрд░ рдкреБрд░рд╛рдиреЗ рд╕реНрддрдВрднред рдЕрдм рдЖрдкрдХрд╛ рдРрдк рд╕рдВрд╕реНрдХрд░рдг 2.0.0
  4. рдХреЙрд▓рдо рд╕реЗ рдорд╛рди рдкрдврд╝реЗрдВ surname, рдпрджрд┐ рдпрд╣ рдирд╣реАрдВ рд╣реИ null, рдпрд╛ рдПрд▓ рд╕реЗast_name, рдЕрдЧрд░ surname рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рд╣реИред рдЖрдк рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВ getLastName() рдХреЛрдб рд╕реЗ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЖрдЙрдЯрдкреБрдЯ рд╣реЛрдЧрд╛ null рдЕрдкрдирд╛ рдЖрд╡реЗрджрди рд╡рд╛рдкрд╕ рд▓рд╛рддреЗ рд╕рдордп 3.0.0 рд╕реЗ 2.0.0.

рдпрджрд┐ рдЖрдк рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдлреНрд▓рд╛рдИрд╡реЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдпреЗ рджреЛ рдЪрд░рдг рд╕рдВрд╕реНрдХрд░рдг рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдХреЗ рджреМрд░рд╛рди рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗ 2.0.0 рдЕрдиреБрдкреНрд░рдпреЛрдЧред рдпрджрд┐ рдЖрдк рдбреЗрдЯрд╛рдмреЗрд╕ рд╡рд░реНрдЬрдирд┐рдВрдЧ рдЯреВрд▓ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХрд╛рдо рдХрд░рдиреЗ рд╣реЛрдВрдЧреЗ (рдкрд╣рд▓реЗ рдбреАрдмреА рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ рдФрд░ рдлрд┐рд░ рдирдпрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рддреИрдирд╛рдд рдХрд░реЗрдВ)ред

рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ рдирд╡ рдирд┐рд░реНрдорд┐рдд рдХреЙрд▓рдо рдирд╣реАрдВ рдЪрд╛рд╣рд┐рдП рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд╢рдХреНрдд рдирд╣реАрдВ. рдпрджрд┐ рдЖрдк рд░реЛрд▓рдмреИрдХ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдкреБрд░рд╛рдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдирдП рдХреЙрд▓рдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рдирд╣реАрдВ рдЪрд▓реЗрдЧрд╛ рдФрд░ рд╡рд╣ рдЗрд╕реЗ рдЗрдВрд╕реНрдЯреЙрд▓ рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ Insert. рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рдпрд╣ рдмрд╛рдзрд╛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдФрд░ рдЖрдкрдХрд╛ рдбреАрдмреА рд╣реЛрдЧрд╛ v2, рдЗрд╕рдХреЗ рд▓рд┐рдП рдирдП рдХреЙрд▓рдо рдХрд╛ рдорд╛рди рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдЬрд┐рд╕рд╕реЗ рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рд╣реЛрдЧрд╛.

рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред рдЖрдкрдХреЛ рд╡рд┐рдзрд┐ рд╣рдЯрд╛ рджреЗрдиреА рдЪрд╛рд╣рд┐рдП getLastName(), рдХреНрдпреЛрдВрдХрд┐ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ 3.0.0 рдХреЛрдб рдореЗрдВ рдХрд┐рд╕реА рдХреЙрд▓рдо рдХреА рдХреЛрдИ рдЕрд╡рдзрд╛рд░рдгрд╛ рдирд╣реАрдВ рд╣реИ last_name. рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╡рд╣рд╛рдВ null рд╕реЗрдЯ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛. рдЖрдк рд╡рд┐рдзрд┐ рдЫреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЪреЗрдХ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ null, рд▓реЗрдХрд┐рди рдПрдХ рдмреЗрд╣рддрд░ рд╕рдорд╛рдзрд╛рди рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рддрд░реНрдХ рдореЗрдВ getSurname() рдЖрдкрдиреЗ рд╕рд╣реА рдЧреИрд░-рд╢реВрдиреНрдп рдорд╛рди рдЪреБрдирд╛ рд╣реИ.

рдП/рдмреА рдкрд░реАрдХреНрд╖рдг

рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕рдВрд╕реНрдХрд░рдг рд╣реИ 1.0.0, рдЙрддреНрдкрд╛рджрди рдкрд░ рддреИрдирд╛рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ v1. рд╣рдореЗрдВ рд╕рдВрд╕реНрдХрд░рдг рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рджреВрд╕рд░рд╛ рдЙрджрд╛рд╣рд░рдг рддреИрдирд╛рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ 2.0.0рдЬреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдЧрд╛ v2.

рдХрджрдо:

  1. рд╕рдВрд╕реНрдХрд░рдг рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рдПрдХ рдирдпрд╛ рдЙрджрд╛рд╣рд░рдг рддреИрдирд╛рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ 2.0.0рдЬреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддрд╛ рд╣реИ v2
  2. рдЗрд╕ рдмреАрдЪ рдХреБрдЫ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрд╕реНрдХрд░рдг рдЙрджрд╛рд╣рд░рдгреЛрдВ рджреНрд╡рд╛рд░рд╛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ 1.0.0
  3. рдЕрджреНрдпрддрди рд╕рдлрд▓ рд░рд╣рд╛ рдФрд░ рдЖрдкрдХреЗ рдкрд╛рд╕ рд╕рдВрд╕реНрдХрд░рдг рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдХрдИ рдЪрд▓ рд░рд╣реЗ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВ 1.0.0 рдФрд░ рдЕрдиреНрдп рд╕рдВрд╕реНрдХрд░рдг 2.0.0. рд╣рд░ рдХреЛрдИ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рд╕рдВрдЪрд╛рд░ рдХрд░рддрд╛ рд╣реИ v2
  4. рд╕рдВрд╕реНрдХрд░рдг 1.0.0 рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЙрдкрдирд╛рдо рдХреЙрд▓рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ 2.0.0 рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ. рд╡реЗ рдПрдХ-рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рд╣рд╕реНрддрдХреНрд╖реЗрдк рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред
  5. рд╕рдВрд╕реНрдХрд░рдг 2.0.0 рдмреИрдХрд╡рд░реНрдб рд╕рдВрдЧрддрддрд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддреЗ рд╣реБрдП, рдбреЗрдЯрд╛ рдХреЛ рдкреБрд░рд╛рдиреЗ рдФрд░ рдирдП рджреЛрдиреЛрдВ рдХреЙрд▓рдо рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ

рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреЛрдИ рдкреНрд░рд╢реНрди рд╣реИ рдЬреЛ рдкреБрд░рд╛рдиреЗ/рдирдП рдХреЙрд▓рдо рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╡рд╕реНрддреБрдУрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдпрд╛рдж рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЕрдм рдЖрдкрдХреЗ рдкрд╛рд╕ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдорд╛рди рд╣реИрдВ (рд╕рдВрднрд╡рддрдГ рд╡реЗ рдЕрднреА рднреА рдорд╛рдЗрдЧреНрд░реЗрдЯ рд╣реЛ рд░рд╣реЗ рд╣реИрдВ)ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдк рдЙрди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдЧрд┐рдирдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬрд┐рдирдХрд╛ рдЕрдВрддрд┐рдо рдирд╛рдо (рдЬреЛ рднреА рдХреЙрд▓рдо рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ) рдЕрдХреНрд╖рд░ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ A, рддрдм рддрдХ рдЬрдм рддрдХ рдбреЗрдЯрд╛ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдкреВрд░рд╛ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ (old тЖТ new column) рдпрджрд┐ рдЖрдк рдХрд┐рд╕реА рдирдП рдХреЙрд▓рдо рдкрд░ рдХреНрд╡реЗрд░реА рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЕрд╕рдВрдЧрдд рдбреЗрдЯрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд░реЛрд▓рдмреИрдХ

рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдРрдк рд╕рдВрд╕реНрдХрд░рдг рд╣реИ 2.0.0 рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ v2.

рдХрджрдо:

  1. рдЕрдкрдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд╡рд╛рдкрд╕ рд░реЛрд▓ рдХрд░реЗрдВ 1.0.0.
  2. рд╕рдВрд╕реНрдХрд░рдг 1.0.0 рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдХрд┐рд╕реА рдХреЙрд▓рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ surname, рдЗрд╕рд▓рд┐рдП рд░реЛрд▓рдмреИрдХ рд╕рдлрд▓ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП

рдбреАрдмреА рдмрджрд▓рддрд╛ рд╣реИ

рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдирд╛рдо рдХрд╛ рдПрдХ рдХреЙрд▓рдо рд╣реЛрддрд╛ рд╣реИ 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');

рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЬреЛрдбрд╝реЗрдВ 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: рдХреЛрдб рд╕реЗ рдЕрдВрддрд┐рдо рдирд╛рдо рд╣рдЯрд╛рдирд╛

рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╕рдВрд╕реНрдХрд░рдг: 3.0.0

рдбреАрдмреА рд╕рдВрд╕реНрдХрд░рдг:v3

рдЯрд┐рдкреНрдкрдгреА

рдЯрд┐рдкреНрдкрдгреА рдкреНрд░рддрд┐.: рдЬрд╛рд╣рд┐рд░рд╛ рддреМрд░ рдкрд░, рдореВрд▓ рд▓реЗрдЦ рдореЗрдВ рд▓реЗрдЦрдХ рдиреЗ рдЧрд▓рддреА рд╕реЗ рдЗрд╕ рдмреНрд▓реЙрдХ рдХреЗ рдкрд╛рда рдХреЛ рдЪрд░рдг 2 рд╕реЗ рдХреЙрдкреА рдХрд░ рд▓рд┐рдпрд╛ рд╣реИред рдЗрд╕ рдЪрд░рдг рдореЗрдВ, рдХреЙрд▓рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рдЙрджреНрджреЗрд╢реНрдп рд╕реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛрдб рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХрд┐рдП рдЬрд╛рдиреЗ рдЪрд╛рд╣рд┐рдП last_name.

рдПрдХ рдирдпрд╛ рдХреЙрд▓рдо рдЬреЛрдбрд╝рдХрд░ рдФрд░ рдЙрд╕рдХреА рд╕рд╛рдордЧреНрд░реА рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдХрд░, рд╣рдордиреЗ рдкрд╢реНрдЪрдЧрд╛рдореА рд╕рдВрдЧрдд рдбреЗрдЯрд╛рдмреЗрд╕ рдкрд░рд┐рд╡рд░реНрддрди рдмрдирд╛рдПред рд╕рд╛рде рд╣реА, рдпрджрд┐ рд╣рдо JAR рдХреЛ рд░реЛрд▓рдмреИрдХ рдХрд░рддреЗ рд╣реИрдВ рдпрд╛ рдХреЛрдИ рдкреБрд░рд╛рдирд╛ JAR рдЪрд╛рд▓реВ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди рдирд╣реАрдВ рдЯреВрдЯреЗрдЧрд╛ред

рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд░реЛрд▓рдмреИрдХ

рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдРрдк рд╕рдВрд╕реНрдХрд░рдг рд╣реИ 3.0.0 рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ v3. рд╕рдВрд╕реНрдХрд░рдг 3.0.0 рдбреЗрдЯрд╛ рдХреЛ рд╕рд╣реЗрдЬрддрд╛ рдирд╣реАрдВ рд╣реИ last_name. рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдореЗрдВ surname рд╕рдмрд╕реЗ рдЕрджреНрдпрддрди рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХреА рдЬрд╛рддреА рд╣реИред

рдХрджрдо:

  1. рдЕрдкрдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд╡рд╛рдкрд╕ рд░реЛрд▓ рдХрд░реЗрдВ 2.0.0.
  2. рд╕рдВрд╕реНрдХрд░рдг 2.0.0 рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдФрд░ last_name ╨╕ surname.
  3. рд╕рдВрд╕реНрдХрд░рдг 2.0.0 рд▓реЗ рдЬрд╛рдПрдЧрд╛ surname, рдпрджрд┐ рдпрд╣ рд╢реВрдиреНрдп рдирд╣реАрдВ рд╣реИ, рдЕрдиреНрдпрдерд╛ -last_name

рдбреЗрдЯрд╛рдмреЗрд╕ рдкрд░рд┐рд╡рд░реНрддрди

рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдХреЛрдИ рд╕рдВрд░рдЪрдирд╛рддреНрдордХ рдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рд╣реИрдВ. рдкреБрд░рд╛рдиреЗ рдбреЗрдЯрд╛ рдХрд╛ рдЕрдВрддрд┐рдо рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХреА рдЬрд╛рддреА рд╣реИ:

-- 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;

рдХреЛрдб рдмрджрд▓рддрд╛ рд╣реИ

рдЯрд┐рдкреНрдкрдгреА рдкреНрд░рддрд┐.: рдЗрд╕ рдмреНрд▓реЙрдХ рдХрд╛ рд╡рд┐рд╡рд░рдг рднреА рд▓реЗрдЦрдХ рджреНрд╡рд╛рд░рд╛ рдЪрд░рдг 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: рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдЕрдВрддрд┐рдо_рдирд╛рдо рд╣рдЯрд╛рдирд╛

рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╕рдВрд╕реНрдХрд░рдг: 4.0.0

рдбреАрдмреА рд╕рдВрд╕реНрдХрд░рдг: v4

рдЯрд┐рдкреНрдкрдгреА

рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рдХрд┐ рд╕рдВрд╕реНрдХрд░рдг рдХреЛрдб 3.0.0 рдХреЙрд▓рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ last_name, рдпрджрд┐ рд╣рдо рд╡рд╛рдкрд╕ рд░реЛрд▓ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди рдХреБрдЫ рднреА рдмреБрд░рд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛ 3.0.0 рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдПрдХ рдХреЙрд▓рдо рд╣рдЯрд╛рдиреЗ рдХреЗ рдмрд╛рджред

рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдирд┐рд╖реНрдкрд╛рджрди рд▓реЙрдЧ

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"}

рдбреАрдмреА рдмрджрд▓рддрд╛ рд╣реИ

рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ 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. рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдкрд░рд┐рдирд┐рдпреЛрдЬрди 1.0.0 ╤Б v1 рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реНрдХреАрдорд╛ (рдХреЙрд▓рдо рдирд╛рдо = last_name)
  2. рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдкрд░рд┐рдирд┐рдпреЛрдЬрди 2.0.0, рдЬреЛ рдбреЗрдЯрд╛ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рддрд╛ рд╣реИ last_name ╨╕ surname. рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реЗ рдкрдврд╝рддрд╛ рд╣реИ last_name. рдбреЗрдЯрд╛рдмреЗрд╕ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд╣реИ v2рдЬреИрд╕реЗ рдХреЙрд▓рдо рдпреБрдХреНрдд last_nameрдФрд░ surname. surname рдПрд▓ рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рд╣реИast_name. (рдиреЛрдЯ: рдЗрд╕ рдХреЙрд▓рдо рдореЗрдВ рд╢реВрдиреНрдп рдмрд╛рдзрд╛ рдирд╣реАрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП)
  3. рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдкрд░рд┐рдирд┐рдпреЛрдЬрди 3.0.0, рдЬреЛ рдХреЗрд╡рд▓ рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ surname рдФрд░ рдЙрдкрдирд╛рдо рд╕реЗ рдкрдврд╝рддрд╛ рд╣реИ. рдЬрд╣рд╛рдБ рддрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рд╕рд╡рд╛рд▓ рд╣реИ, рдЕрдВрддрд┐рдо рдорд╛рдЗрдЧреНрд░реЗрд╢рди рд╣реЛ рд░рд╣рд╛ рд╣реИ last_name ╨▓ surname. рдпрд╣ рднреА рдПрдХ рд╕реАрдорд╛ рд╣реИ рдЕрд╢рдХреНрдд рдирд╣реАрдВ рд╕реЗ рдирд┐рдХрд╛рд▓рд╛ рдЧрдпрд╛ last_name. рдбреЗрдЯрд╛рдмреЗрд╕ рдЕрдм рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд╣реИ v3
  4. рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдкрд░рд┐рдирд┐рдпреЛрдЬрди 4.0.0 - рдХреЛрдб рдореЗрдВ рдХреЛрдИ рдмрджрд▓рд╛рд╡ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ. рдбреЗрдЯрд╛рдмреЗрд╕ рдкрд░рд┐рдирд┐рдпреЛрдЬрди v4, рдЬреЛ рд╣рдЯрд╛ рджреЗрддрд╛ рд╣реИ last_name. рдпрд╣рд╛рдВ рдЖрдк рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдХреЛрдИ рднреА рдЫреВрдЯреА рд╣реБрдИ рдмрд╛рдзрд╛ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред

рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдкрд╛рд▓рди рдХрд░рдХреЗ рдЖрдк рдбреЗрдЯрд╛рдмреЗрд╕/рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЕрдиреБрдХреВрд▓рддрд╛ рдХреЛ рддреЛрдбрд╝реЗ рдмрд┐рдирд╛ рд╣рдореЗрд╢рд╛ рдПрдХ рд╕рдВрд╕реНрдХрд░рдг рд╡рд╛рдкрд╕ рд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдХреЛрдб

рдЗрд╕ рдЖрд▓реЗрдЦ рдореЗрдВ рдкреНрд░рдпреБрдХреНрдд рд╕рднреА рдХреЛрдб рдпрд╣рд╛рдВ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ Github. рдиреАрдЪреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рд╡рд┐рд╡рд░рдг рд╣реИ.

рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ

рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЛ рдХреНрд▓реЛрди рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдкрдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝реЛрд▓реНрдбрд░ рд╕рдВрд░рдЪрдирд╛ рджрд┐рдЦрд╛рдИ рджреЗрдЧреАред

тФЬтФАтФА 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/scenario_backward_compatible.sh

рдФрд░ рджреЗрдЦрдирд╛ рд╣реИ рдкрд╢реНрдЪрдЧрд╛рдореА рдЕрд╕рдВрдЧрдд рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рд╡рд╛рд▓рд╛ рдорд╛рдорд▓рд╛, рджреМрдбрд╝рдирд╛:

./scripts/scenario_backward_incompatible.sh

рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдирдореВрдирд╛ рдлреНрд▓рд╛рдИрд╡реЗ

рд╕рднреА рдЙрджрд╛рд╣рд░рдг рдпрд╣реАрдВ рд╕реЗ рд▓рд┐рдП рдЧрдП рд╣реИрдВ Spring Boot Sample Flyway.

рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ http://localhost:8080/flyway, рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреА рдПрдХ рд╕реВрдЪреА рд╣реИред

рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ H2 рдХрдВрд╕реЛрд▓ (at) рднреА рд╢рд╛рдорд┐рд▓ рд╣реИ http://localhost:8080/h2-console) рддрд╛рдХрд┐ рдЖрдк рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реНрдерд┐рддрд┐ рджреЗрдЦ рд╕рдХреЗрдВ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ jdbc URL рд╣реИ jdbc:h2:mem:testdb).

рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд

рд╣рдорд╛рд░реЗ рдмреНрд▓реЙрдЧ рдкрд░ рдЕрдиреНрдп рд▓реЗрдЦ рднреА рдкрдврд╝реЗрдВ:

рд╕реНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╝реЗрдВ