liquibase w praktyce

30
Liquibase w praktyce Mateusz Lubański JUG Bielsko-Biala 1 września 2016 Mateusz Lubański Liquibase w praktyce 1 września 2016 1 / 30

Upload: mateusz-lubanski

Post on 17-Jan-2017

75 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Liquibase w praktyce

Liquibase w praktyce

Mateusz Lubański

JUG Bielsko-Biała

1 września 2016

Mateusz Lubański Liquibase w praktyce 1 września 2016 1 / 30

Page 2: Liquibase w praktyce

O mnie

Java Developer 5+Technologie backendoweObecnie pracuje w Omnetric

Fan Agile i ScrumHobby: narty/kajaki/trekking//salsa

http://linkedin.com/in/mateuszlubanski

Mateusz Lubański Liquibase w praktyce 1 września 2016 2 / 30

Page 3: Liquibase w praktyce

Podstawowe problemy w zarządzaniu bazą

śledzenie zmian

dane słownikowe

dane testowe

automatyzacja

wersjonowanie

niezależny od środowiska

łatwy

Mateusz Lubański Liquibase w praktyce 1 września 2016 3 / 30

Page 4: Liquibase w praktyce

Istniejące rozwiązania

Liquibase

złożony

xml, yaml, json, sql<databaseChangeLog>

<changeSet id=”1” author=”mlubanski”><sqlFile path=”V1.sql” />

</changeSet><changeSet id=”2” author=”mlubanski”>

<sqlFile path=”V2.sql” /></changeSet>

<databaseChangeLog>

Flyway

prosty

sqlV1.sqlV2.sqlV3.sql

Mateusz Lubański Liquibase w praktyce 1 września 2016 4 / 30

Page 5: Liquibase w praktyce

Integracja

Command Line

Maven

Spring-Boot

Mateusz Lubański Liquibase w praktyce 1 września 2016 5 / 30

Page 6: Liquibase w praktyce

Command Line Integration

full commandjava −jar ./liquibase−core−3.5.1.jar \−−driver=org.postgresql.Driver \−−classpath=./postgresql−9.2−1002−jdbc4.jar \−−changeLogFile=src/main/resources/db/changelog/db.changelog−master.xml \−−url=”jdbc:postgresql://localhost:5432/sampledb” \−−username=sample \−−password=topsecret \update

using liquibase.propertiesdriver: org.postgresql.Driverclasspath: ./postgresql−9.2−1002−jdbc4.jarurl: jdbc:postgresql://localhost:5432/sampledbusername: samplepassword: topsecret

java −jar ./liquibase−core−3.5.1.jar \−−changeLogFile=src/main/resources/db/changelog/db.changelog−master.xml \update

Mateusz Lubański Liquibase w praktyce 1 września 2016 6 / 30

Page 7: Liquibase w praktyce

Maven Integration

dependency<dependency>

<groupId>org.liquibase</groupId><artifactId>liquibase−core</artifactId><version>3.5.1</version>

</dependency>

plugin<plugin>

<groupId>org.liquibase</groupId><artifactId>liquibase−maven−plugin</artifactId><version>3.5.1</version><configuration>

<propertyFile>src/main/resources/liquibase/liquibase.properties</propertyFile><changeLogFile>src/main/resources/db/changelog/db.changelog−master.xml</changeLogFile>

</configuration><executions>

<execution><goals>

<goal>update</goal></goals>

</execution></executions>

</plugin>

commandmvn liquibase:update

Mateusz Lubański Liquibase w praktyce 1 września 2016 7 / 30

Page 8: Liquibase w praktyce

Spring-Boot Integration

dependency<dependency>

<groupId>org.liquibase</groupId><artifactId>liquibase−core</artifactId>

</dependency>

plugin<plugin>

<groupId>org.springframework.boot</groupId><artifactId>spring−boot−maven−plugin</artifactId>

</plugin>

application.propertiesliquibase.enabled=trueliquibase.change−log=classpath:/db/changelog/db.changelog−master.xml

spring.datasource.url=jdbc:postgresql://localhost:5432/sampledbspring.datasource.username=samplespring.datasource.password=secret

commandmvn spring−boot:run

Mateusz Lubański Liquibase w praktyce 1 września 2016 8 / 30

Page 9: Liquibase w praktyce

Struktura xml

databaseChangeLog

preConditions

property

changeSet

include

changeSet

comment

preConditions

Any Refactoring Tag(s)

rollback

Mateusz Lubański Liquibase w praktyce 1 września 2016 9 / 30

Page 10: Liquibase w praktyce

Pierwszy changeSet

sql<changeSet id=”1” author=”mlubanski”>

<sqlFile relativeToChangelogFile=”true” path=”sql/create person.sql”/></changeSet>

CREATE TABLE person(

id serial NOT NULL,name character varying(100) NOT NULL,date date DEFAULT now(),CONSTRAINT pk person PRIMARY KEY (id),CONSTRAINT person name key UNIQUE (name)

);

xml<changeSet id=”2” author=”mlubanski”>

<createTable tableName=”USER”><column name=”ID” type=”int” autoIncrement=”true” >

<constraints primaryKey=”true” nullable=”false” /></column><column name=”NAME” type=”varchar(100)” >

<constraints nullable=”false” unique=”true”/></column><column name=”DATE” type=”date” defaultValueComputed=”now()”>

<constraints nullable=”false” /></column>

</createTable></changeSet>

Mateusz Lubański Liquibase w praktyce 1 września 2016 10 / 30

Page 11: Liquibase w praktyce

Skąd Liquibase wie który skrypt został już wykonany?

id musi być unikalne dla changeLog’a i użytkownika

Liquibase generuje i zapisuje md5sum dla każdego wykonanegochangeSet’a

Główna idea liquibase’a to ciągła liniowa sekwencja zmian na baziedanych. Podobnie jak przy Versioning Control System niemodyfikujemy starych commit’ów tak przy liquibas’e niemodyfikujemy starych changeSet’ów ponieważ możemy zerwaćspójność bazy danych.

Mateusz Lubański Liquibase w praktyce 1 września 2016 11 / 30

Page 12: Liquibase w praktyce

Skąd Liquibase wie który skrypt został już wykonany?

DATABASECHANGELOGLOCK (liquibase releaseLocks)

LOCKED

LOCKGRANTED

LOCKEDBY

DATABASECHANGELOG

ID

AUTHOR

FILENAME

DATEEXECUTED

EXECTYPE [EXECUTED, FAILED, SKIPPED, RERAN, MARKRAN]

MD5SUM

DESCRIPTION

Mateusz Lubański Liquibase w praktyce 1 września 2016 12 / 30

Page 13: Liquibase w praktyce

Wspierane Refactorings

create: table, view, procedure, sequence, index

add: column, foreign key, not null, unique, default value, primary key,autoincrement

drop: ...

rename: column, table, view,

others: insert, load data, sql, sqlFile, modify data type, update

Mateusz Lubański Liquibase w praktyce 1 września 2016 13 / 30

Page 14: Liquibase w praktyce

Wspierane bazy danych

MySQL

PostgreSQL

Oracle

Sql Server

Sybase

DB2

Apache Derby

HSQL

H2

Informmix

Firebird

SQLite

Mateusz Lubański Liquibase w praktyce 1 września 2016 14 / 30

Page 15: Liquibase w praktyce

Wykonywanie tego samego changeSet wielokrotnie

<databaseChangeLog><changeSet id=”3” author=”mlubanski” runOnChange=”true”>

<sqlFile path=”deactivate user procedure.sql” splitStatements=”false” /><rollback>DROP PROCEDURE DEACTIVATE USER;</rollback>

</changeSet>

<changeSet id=”4” author=”mlubanski” runAlways=”true” ><sqlFile path=”clean deactivated users.sql” splitStatements=”false” />

</changeSet><databaseChangeLog>

Mateusz Lubański Liquibase w praktyce 1 września 2016 15 / 30

Page 16: Liquibase w praktyce

Wprowadzanie danych

changelog.xml<changeSet author=”mlubanski” id=”5” runOnChange=”true”>

<loadData tableName=”COUNTRY” file=”data/countries.csv” ><column name=”name” type=”STRING” /><column name=”sequence” type=”NUMERIC” />

</loadData><rollback>

DELETE FROM COUNTRY;</rollback>

</changeSet>

countries.csvname,sequencePolska,1Austria,2Niemcy,3Anglia,4

Mateusz Lubański Liquibase w praktyce 1 września 2016 16 / 30

Page 17: Liquibase w praktyce

Context

changelog.xml<changeSet author=”mlubanski” id=”5” runOnChange=”true” context=”dev”>...</changeSet>

Spring-Boot application.propertiesliquibase.contexts=dev

Maven plugin<plugin>

<groupId>org.liquibase</groupId><artifactId>liquibase−maven−plugin</artifactId>

<configuration><contexts>dev</contexts>...

</configuration></plugin>

Command Linejava −jar ./liquibase−core−3.5.1.jar \−−changeLogFile=src/main/resources/db/changelog/db.changelog−master.xml \−−contexts=dev \update

Mateusz Lubański Liquibase w praktyce 1 września 2016 17 / 30

Page 18: Liquibase w praktyce

Preconditions

Warunki zadeklarowane na poziomie changeLog mają globalny zakres dowszystkich changeSet’ów<preConditions>

<or><dbms type=”h2” /><dbms type=”mysql” />

</or></preConditions>

<changeSet id=”6” author=”mlubanski”><preConditions onFail=”WARN”>

<sqlCheck expectedResult=”0”>select count(∗) from oldtable</sqlCheck></preConditions><dropTable tableName=”oldtable”/>

</changeSet>

onFail: HALT, CONTINUE, MARK RAN, WARN<changeSet id=”7” author=”mlubanski” dbms=”postgresql”>

<sqlFile path=”insert.sql” /></changeSet>

Mateusz Lubański Liquibase w praktyce 1 września 2016 18 / 30

Page 19: Liquibase w praktyce

Preconditions

Dostępne warunki:

dbms

changeSetExecuted

columnExists, tableExists, viewExists, foreignKeyConstraintExists,sequenceExists, primaryKeyExists

sqlCheck

changeLogPropertyDefined

customPrecondition

Mateusz Lubański Liquibase w praktyce 1 września 2016 19 / 30

Page 20: Liquibase w praktyce

Property and Include

Property:<property name=”key.type” value=”NUMERIC(10,0)” /><property name=”name.type” value=”VARCHAR(255)”/><property name=”text.type” value=”VARCHAR(2000)” /><property name=”now” value=”SYSDATE ” dbms=”oracle” /><property name=”now” value=”NOW()” dbms=”postgresql” />

<changeSet id=”8” author=”mlubanski”><createTable tableName=”MESSAGE”>

<column name=”ID” type=”${key.type}” autoIncrement=”true”><constraints primaryKey=”true” nullable=”false” />

</column><column name=”TITLE” type=”${name.type}”>

<constraints nullable=”false” /></column><column name=”CONTENT” type=”${text.type}” /><column name=”DATE” type=”date” defaultValueComputed=”${now}”>

<constraints nullable=”false” /></column>

</createTable></changeSet>

Include:<include file=”R1/db.changelog−master.xml” relativeToChangelogFile=”true” /><include file=”dev/sample−data.changelog.xml” relativeToChangelogFile=”true” context=”dev” />

Mateusz Lubański Liquibase w praktyce 1 września 2016 20 / 30

Page 21: Liquibase w praktyce

Przykładowa struktura

dbchangelogdb.changelog.dev.xmldb.changelog.production.xmlR1datadictionary.csv

db.changelog.2016-08.20.xmldb.changelog.2016-08.21.xmldb.changelog.master.xml

R2datadictionary.csv

db.changelog.2016-08.20.xmldb.changelog.2016-08.21.xmldb.changelog.master.xml

Mateusz Lubański Liquibase w praktyce 1 września 2016 21 / 30

Page 22: Liquibase w praktyce

Przykładowa struktura

db\changelog\db.changelog.dev.xml<property name=”key.type” value=”NUMERIC(10,0)” /><property name=”name.type” value=”VARCHAR(255)”/>...

<include file=”R1/db.changelog.master.xml” relativeToChangelogFile=”true” /><include file=”R2/db.changelog.master.xml” relativeToChangelogFile=”true” />

db\changelog\R1\db.changelog.master.xml<include file=”db.changelog.2016−08.20.xml” relativeToChangelogFile=”true” /><include file=”db.changelog.2016−08.20.xml” relativeToChangelogFile=”true” />

Mateusz Lubański Liquibase w praktyce 1 września 2016 22 / 30

Page 23: Liquibase w praktyce

Jak wdrożyć liquibase do istniejącego projektu

1 Generujemy changeLog’a (komenda ta nie eksportuje: Storedprocedures, functions, packages, Triggers)java −jar ./liquibase−core−3.5.1.jar \db.changelog.xml \generateChangeLog

2 Odpalamy changelogSync który wypełnia nam tabelęDATABASECHANGELOG wpisami z changeSet’ów bez wykonywaniaich na baziejava −jar ./liquibase−core−3.5.1.jar \db.changelog.xml \changeLogSync

Mateusz Lubański Liquibase w praktyce 1 września 2016 23 / 30

Page 24: Liquibase w praktyce

Przydatne triki

Co gdy admin na powie, że on musi mieć SQL’a? :)java −jar ./liquibase−core−3.5.1.jar \src/main/resources/db/changelog/db.changelog−master.xml \updateSQL > /tmp/script.sql

Czy na pewno baza A jest taka sama jak baza B?java −jar ./liquibase−core−3.5.1.jar \diffChangeLog−−referenceUrl=”jdbc:postgresql://localhost:5432/B” \−−referenceUsername=sample \−−referencePassword=topsecret \> diff.database.changelog.xml

Diff Nie wspiera: Non-foreign key constraints (check, etc), StoredProcedures, Data type length

Mateusz Lubański Liquibase w praktyce 1 września 2016 24 / 30

Page 25: Liquibase w praktyce

Warto wspomnieć?

dbDocCurrent TablesAuthorsChange LogsPending ChangesPending SQLMost Recent Changes

RollbackLiczbaDataTag

Mateusz Lubański Liquibase w praktyce 1 września 2016 25 / 30

Page 26: Liquibase w praktyce

Podsumowanie

śledzenie zmian - spersonalizowane changeSet’y zapisywane w baziewraz z dbDoc

dane słownikowe - loadData + .csv

dane testowe - contexts

automatyzacja - libuibase:update

wersjonowanie - include + odpowiednia struktura

niezależny od środowiska - xml

łatwy - umiarkowanie łatwy z wielkimi możliwościami

Mateusz Lubański Liquibase w praktyce 1 września 2016 26 / 30

Page 27: Liquibase w praktyce

Demo Time :)

Mateusz Lubański Liquibase w praktyce 1 września 2016 27 / 30

Page 28: Liquibase w praktyce

Pytania?

Mateusz Lubański Liquibase w praktyce 1 września 2016 28 / 30

Page 29: Liquibase w praktyce

Dziękuję za uwagę :)

Mateusz Lubański Liquibase w praktyce 1 września 2016 29 / 30

Page 30: Liquibase w praktyce

Przydatne linki

http://www.liquibase.org/documentation/index.html

http://www.liquibase.org/documentation/changes/

http://projects.spring.io/spring-boot/

http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

http://www.slideshare.net/MateuszLubaski/liquibase-w-praktyce

https://github.com/mlubanski/questionnarie-server

Mateusz Lubański Liquibase w praktyce 1 września 2016 30 / 30