Giriş
flyway'i komut satırından kullanabilmek için kurmak gerekir. Kurma işlemi aslında sadece zip dosyasını indirip açmak ve Path'e eklemekten ibaret. Şöyle yaparız
export PATH=$PATH:$HOME/flyway-9.3.0
Komut satırından 7 seçenek kullanılabilir.
migrate
clean
info
validate
undo
baseline
repair
migrate seçeneği
Şöyle yaparız
flyway migrate -configFiles=flyway.properties
Docker Olarak Kullanım
Örnek
compose.yaml dosyasında şöyle yaparız. Projeye Docker Compose Desteği ekleyince flyway otomatik çalışır
# FILE: compose.yaml version: '3' services: postgres: image: 'postgres:15' container_name: "postgres" environment: - 'POSTGRES_DB=postgres' - 'POSTGRES_PASSWORD=postgres' - 'POSTGRES_USER=postgres' ports: - '5432:5432' flyway: # Use Docker image containing Flyway CLI image: flyway/flyway:9.22.1 container_name: "flyway-migration" # Execute migration command with input parameters on container startup command: -locations=filesystem:/flyway/migration -user=postgres -password=postgres -url="jdbc:postgresql://postgres:5432/postgres" -connectRetries=5 migrate # Copy migration script folder into container volumes: - ./db/migration:/flyway/migration # Wait for Postgres container to start depends_on: - postgres
Kütüphane Olarak Kullanım
1. Flyway maven veya gradle dependency eklenir
2. Ayrıca "spring.jpa.hibernate.ddl-auto : none" olmalıdır
3. application.properties dosyasında data source tanımlanır. Flyway için herhangi bir ayar belirtmemize gerek yok. Varsayılan ayarlar yeterli.
Örnek
Şöyle yaparız
server: port: ${port:8080} spring: application: name: flyway-demo datasource: driver-class-name: org.h2.Driver username: sa password: url: "jdbc:h2:mem:db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_LOWER=TRUE;CASE_INSENSITIVE_IDENTIFIERS=TRUE" h2: console: enabled: true path: /h2-console jpa: show-sql: true hibernate: ddl-auto: none
Şöyle yaparız. Böylece uygulama çalışırken schema migration (şema taşınması/değiştirilmesi) yapılabilir.
<dependency><groupId>org.flywaydb</groupId><artifactId>flyway-core</artifactId><version>6.5.5</version></dependency>
Açıklaması şöyle
With this, Flyway automatically scans the classpath looking for the migration scripts, and executes them against the database during application startup. By default, it scans for files located in classpath:db/migration.
Açıklaması şöyle
Flyway creates a special table called the “Flyway Schema History” to store metadata, such as script name, migration version, execution status, execution date-time, etc.
Then, to keep track of the schema evolution, it logs the metadata into this table, leaving the Flyway Schema History table as the only source of truth, and allowing Flyway to check if a new migration script has been added.
In addition, it validates the integrity of older scripts using a checksum stored in the table. So, if any of the scripts in the table has been modified, the application will fail to start.
Şeklen şöyle. Bu tabloyu flyway ilk kez çalışırken yaratır. Değişiklikleri bu tabloda takip eder. Böylece bir script ikinci kez çalıştırılmaz
Tablonun satırları şöyle| installed_rank | version | description | type | script | checksum | installed_by | installed_on | execution_time | success | |----------------|---------|--------------|------|------------------------|------------|--------------|----------------|----------------|---------| | 1 | 1 | post tag | SQL | V1_0__post_tag.sql | -611721954 | postgres | 30-06-20 15:21 | 61 | TRUE | | 2 | 1.1 | post details | SQL | V1_1__post_details.sql | 511495203 | postgres | 30-06-20 15:21 | 13 | TRUE | | 3 | 1.2 | post comment | SQL | V1_2__post_comment.sql | 762350400 | postgres | 30-06-20 15:21 | 14 | TRUE | | 4 | 1.3 | users | SQL | V1_3__users.sql | -596399497 | postgres | 30-06-20 15:55 | 32 | TRUE |
Checksum Hatası
Hata şöylee
org.flywaydb.core.api.FlywayException: Validate failed: Migration checksum mismatch for migration version .
Açıklaması şöyle
What is it?The checksum validation from Flyway is basically a check between the checksum of the current migration file in your app against the checksum from the same migration it already run in the past. You can check this list on your database, under flyway_schema_history table created and used by Flyway.What it means?It means that the script you app has when it starts is not the same Flyway already applied in the past and since it can't figure out if that is correct or not, it fails. Ideally, you should never change a script you already applied, you should always evolve and create new ones, that's the whole idea about migrations.How to avoid it?As said before, you should never change scripts that were already executed before. You should always create new ones. Of course if that happens on a dev environment and you figure out changes are needed.
application.properties
application.properties yazısına taşıdım
Script Dizini
Veri tabanı scriptleri için varsayılan dizin şöyledir
src/resources/db/migration
Çift alt çizgi kullanılması gerekir. Açıklaması şöyle
Make sure you have double underscores present after the version of a file, i.e “V1__FILENAME.sql”, if you provide a single underscore after the version file is skipped when starting the application by Flyway, i.e “V1_FILENAME.sql”.V1__create_book_table.sqlV1.1__insert_into_books.sql
Şeklen şöyle
V ile başlayanlar dışında U ve R ile de başlayan dosya isimleri olabilir. Şeklen şöyleAçıklaması şöyle
Part 1: It is the letter “v” in uppercase. The name always starts with this letter.Part 2: It is the migration version; it can be 1, 001, 1.2.3, 2021.09.24.12.55.32, … you got it.Part 3: It is the two underscores (_)Part 4: The description of the migration; you can separate words with an underscore or a space.Part 5: It is the extension of the file .sql
Açıklaması şöyle
The Part 1, 3 and 5 are configurable using the configuration file with this properties: spring.flyway.sql-migration-prefix, spring.flyway.sql-migration-separator, spring.flyway.sql-migration-suffixes.spring.flyway.sql-migration-prefix=Tspring.flyway.sql-migration-separator=--spring.flyway.sql-migration-suffixes=.blogThe migration file will be: T1.0 — create_users_table.blog
Açıklaması şöyle.
sql statement should end with ‘;’ or cause execute fail.
Örnek - V1.0__initial_schema.sql
Şöyledir. Burada V1.0 ismi kullanılıyor
-- V1.0__initial_schema.sql CREATE TABLE author ( ID BIGINT NOT NULL AUTO_INCREMENT, NAME VARCHAR(100) NOT NULL UNIQUE, BIRTH_YEAR INT NOT NULL, CONSTRAINT pk_author PRIMARY KEY (ID) ); CREATE TABLE book ( ID BIGINT NOT NULL AUTO_INCREMENT, TITLE VARCHAR(150) NULL, PUB_DATE datetime NULL, AUTHOR BIGINT NULL, CONSTRAINT pk_book PRIMARY KEY (ID) ); ALTER TABLE book ADD CONSTRAINT uc_book_title UNIQUE (TITLE); ALTER TABLE book ADD CONSTRAINT FK_BOOK_ON_AUTHOR FOREIGN KEY (AUTHOR) REFERENCES author (ID);
Örnek - V1_create_person.sql
Şöyledir. Burada V1 ismi kullanılıyor
create table person(id serial primary key,first_name text,last_name text,date_created timestamp with time zone);
Örnek
Eğer uygulamayı çalıştırmadan sadece Flyway işini yapsın istersek şöyle yaparız
Örnek - Testimport static org.springframework.boot.WebApplicationType.NONE;import org.springframework.boot.SpringApplication;import org.springframework.boot.SpringBootConfiguration;import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;import org.springframework.boot.builder.SpringApplicationBuilder;import org.springframework.context.annotation.Import;/*** Utility to run flyway migration without starting service*/@SpringBootConfiguration@Import({DataSourceAutoConfiguration.class, FlywayAutoConfiguration.class})public class FlywayMigrationRunner {public static void main(String[] args) {SpringApplication application =new SpringApplicationBuilder(FlywayMigrationRunner.class).web(NONE).build();application.run(args);}}
Eğer Flyway'i testlerde kullanmak istermezsek şöyle yaparız. application-test-containers.yml içinde flyway'i kapatırız
spring:datasource:url: jdbc:tc:postgresql:9.6.8:///test_databaseusername: userpassword: passwordjpa:hibernate:ddl-auto: createflyway:enabled: false
application-test-containers-flyway.yml içinde yeni konfigürasyon yazarız
spring:datasource:url: jdbc:tc:postgresql:9.6.8:///test_databaseusername: userpassword: password
Test içinde ActiveProfile ile kullanırız
@SpringBootTest(webEnvironment = WebEnvironment.NONE)@Testcontainers@ActiveProfiles("test-containers-flyway")class PersonCreateServiceImplTestContainersFlyway {@Autowiredprivate PersonRepository personRepository;@MockBeanprivate PersonValidateService personValidateService;@Autowiredprivate PersonCreateService personCreateService;@BeforeEachvoid init() {personRepository.deleteAll();}@Testvoid shouldCreateOnePerson() {final var people = personCreateService.createFamily(List.of("Simon"),"Kirekov");assertEquals(1, people.size());final var person = people.get(0);assertEquals("Simon", person.getFirstName());assertEquals("Kirekov", person.getLastName());assertTrue(person.getDateCreated().isBefore(ZonedDateTime.now()));}@Testvoid shouldRollbackIfAnyUserIsNotValidated() {doThrow(new ValidationFailedException("")).when(personValidateService).checkUserCreation("John", "Brown");assertThrows(ValidationFailedException.class, () -> personCreateService.createFamily(List.of("Matilda", "Vasya", "John"),"Brown"));assertEquals(0, personRepository.count());}}
Hiç yorum yok:
Yorum Gönder