Database migration sử dụng Flyway

Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh

Mình đã giới thiệu với các bạn về database migration sử dụng Liquibase. Flyway cũng làm được điều tương tự nhưng cách hoạt động đơn giản hơn nhiều. Nó không cần phải sử dụng đến một table lock trong quá trình chạy migration. Cụ thể như thế nào? Hãy cùng nhau tìm hiểu trong bài viết này, các bạn nhé!

  "Làm PM, theo anh không cần biết về code, nhưng phải hiểu về SQL, database, những khái niệm cơ bản của code"
  Các thao tác cơ bản với Database SQL Server (tạo mới database, table,...)

Xem thêm các việc làm Database lương cao trên TopDev

Đầu tiên, mình sẽ tạo mới một Maven project để làm ví dụ:

Database migration sử dụng Flyway

với Flyway và PostgreSQL JDBC driver dependencies như sau:

<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>7.12.0</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.23</version>
</dependency>

Mình cũng sử dụng Java 8 cho ví dụ này:

<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>

Với Flyway thì chúng ta có thể sử dụng tập tin SQL hoặc code Java để hiện thực database migration, thông thường thì mình sử dụng tập tin SQL vì đơn giản hơn rất nhiều. Trong bài viết này, mình sẽ sử dụng tập tin SQL để làm ví dụ, các bạn muốn sử dụng code Java thì có thể đọc thêm ở đây nhé.

Với tập tin SQL thì Flyway, sau khi có connection tới database, sẽ đọc các tập tin SQL này ở một thư mục mà chúng ta cấu hình, mặc định là thư mục src/main/resources/db/migration để làm migration.

Tên của các tập tin SQL cần phải đặt theo một naming convention nhất định các bạn nhé!

Flyway hỗ trợ chúng ta có thể migrate với một version mới cho database structure bằng một tập tin SQL mới hoặc có thể sử dụng chỉ duy nhất một tập tin SQL với repeatable migration hoặc undo một version nào đó. Lưu ý là undo migration chỉ available cho phiên bản Flyway Teams edition các bạn nhé! Các bạn cũng có thể khai báo một tập tin mới và viết SQL script để remove những thông tin mà mình muốn remove, không cần sử dụng undo migration cũng được.

Dưới đây là một ví dụ về tên của tập tin SQL:

  • V2021.07.31.00000__Init nếu thêm version mới
  • R__People_view.sql nếu là repeatable migration
  • U2__Add_people.sql nếu là undo version.

Tên tập tin sẽ bắt đầu với ký tự V hoặc R hoặc U tuỳ theo cách mà các bạn muốn làm migration như ví dụ trên. Tiếp theo sẽ là version, naming convention cho version thì các bạn có thể tham khảo tại đây, mình thì thường sử dụng version theo ngày tháng năm như ví dụ trên.

Ngăn cách giữa 2 phần trong tên của tập tin SQL là 2 ký tự gạch dưới “__”, phần phía sau 2 dấu gạch dưới này là mô tả về thay đổi mà các bạn làm trong tập tin SQL này.

Để làm ví dụ cho bài viết này, mình sẽ tạo mới một tập tin SQL với tên là V2021.08.07.00000__Init với nội dung tạo mới table student như sau:

CREATE TABLE student (
ID INT PRIMARY KEY,
name VARCHAR(250) NOT NULL
);

Bây giờ, mình sẽ tạo mới một main class để xem cách làm việc của Flyway như thế nào các bạn nhé.

Nội dung của class này ban đầu như sau:

package com.huongdanjava.flyway;

public class Application {

public static void main(String[] args) {

}

}

Chúng ta sẽ sử dụng đối tượng của class Flyway, khởi tạo nó cùng với thông tin Datasource kết nối tới database để chuẩn bị làm migration, như sau:

Flyway flyway = Flyway.configure()
.dataSource("jdbc:postgresql://localhost:5432/student", "postgres", "123456")
.load();

Nếu các bạn đã có thông tin Datasource rồi thì cũng có thể sử dụng một phương thức overload khác để sử dụng Datasource này:

Database migration sử dụng Flyway

không cần phải khai báo databaseURL, username và password như mình.

Để chạy migration, chúng ta sẽ gọi phương thức migrate() của đối tượng Flyway như sau:

flyway.migrate();

Bây giờ, nếu chạy ví dụ này, rồi kiểm tra database, các bạn sẽ thấy kết quả như sau:

Database migration sử dụng Flyway

Ngoài table student mà chúng ta đã khai báo trong tập tin SQL, Flyway còn tạo một table khác tương tự như Liquibase để quản lý tất cả các version mà chúng ta đã chạy. Table này tên là flyway_schema_history, dùng để keep track history:

Database migration sử dụng Flyway

Như các bạn thấy, Flyway extract thông tin về version từ tên của tập tin SQL. Nó còn sử dụng một column để lưu trữ checksum của tập tin SQL để kiểm tra tập tin SQL nào đã chạy, tập tin nào chưa. Các bạn không được thay đổi nội dung của những tập tin mà Flyway đã chạy migration, nếu có bất kỳ thay đổi nào thì Flyway sẽ báo lỗi ngay.

Nếu các bạn muốn thêm một version mới thì cứ tạo mới tập tin SQL theo naming convention mà mình đã nói ở trên là được nhé!

Ví dụ mình thêm mới cột address cho student thì mình sẽ tạo mới tập tin SQL với tên V2021.08.07.00001__add_student_address và nội dung như sau:

ALTER TABLE student 
ADD COLUMN address VARCHAR(255);

Kết quả:

Database migration sử dụng Flyway