Liquibase und Maven

Einführung


Liquibase ist ein Datenbankversionskontrollsystem, das hauptsächlich die Struktur und in geringerem Maße den Inhalt der Datenbank betrifft. Gleichzeitig ist die Beschreibung der Datenbank einerseits recht abstrakt und ermöglicht die Verwendung verschiedener DBMS auf der unteren Ebene, andererseits können Sie jederzeit zum SQL-Dialekt eines bestimmten DBMS wechseln, der sehr flexibel ist. Liquibase ist ein etabliertes Open Source-Projekt und wird außerhalb seiner nativen Java-Umgebung aktiv verwendet. Für die Arbeit sind keine umfassenden Java-Kenntnisse erforderlich. In der Vergangenheit wurde ein XML-Format verwendet, um die Basisstruktur und Basisänderungen zu beschreiben. Jetzt werden YAML und JSON parallel unterstützt.


In diesem Artikel werden wir die Erfahrungen früherer Generationen kurz zusammenfassen und uns auf die Arbeit mit Liquibase mit Maven konzentrieren. Wir werden Ubuntu als Testbetriebssystem verwenden.


Andere Artikel über Liquibase



Umgebungseinstellung


Es gibt verschiedene Möglichkeiten, Liquibase zu starten. Am bequemsten ist es jedoch, Maven oder Gradle zu verwenden.


sudo apt install maven mvn -version 

Hier fungiert pom.xml als Makefile - es enthält bereits alle notwendigen Abhängigkeiten, Einstellungen und Profile.


pom.xml
 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.test.db</groupId> <artifactId>db</artifactId> <version>1.0.0</version> <name>db</name> <description>Test Database</description> <packaging>pom</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <slf4j.version>1.7.24</slf4j.version> <logback.version>1.2.3</logback.version> <liquibase.version>3.6.2</liquibase.version> <postgresql.version>42.2.5</postgresql.version> <snakeyaml.version>1.23</snakeyaml.version> </properties> <dependencies> <!--Logging--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> </dependency> <!--JDBC drivers--> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>${postgresql.version}</version> </dependency> <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> <version>${liquibase.version}</version> </dependency> <dependency> <groupId>org.yaml</groupId> <artifactId>snakeyaml</artifactId> <version>${snakeyaml.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.liquibase</groupId> <artifactId>liquibase-maven-plugin</artifactId> <version>${liquibase.version}</version> <configuration> <propertyFile>${profile.propertyFile}</propertyFile> <changeLogFile>${profile.changeLogFile}</changeLogFile> <dataDir>${profile.dataDir}</dataDir> <!-- log --> <verbose>${profile.verbose}</verbose> <logging>${profile.logging}</logging> <promptOnNonLocalDatabase>false</promptOnNonLocalDatabase> </configuration> </plugin> </plugins> </build> <profiles> <!-- Development settings, -Denv=dev --> <profile> <id>dev</id> <activation> <property> <name>env</name> <value>dev</value> </property> </activation> <properties> <profile.propertyFile>dev/liquibase.properties</profile.propertyFile> <profile.changeLogFile>dev/master.xml</profile.changeLogFile> <profile.dataDir>dev/data</profile.dataDir> <profile.verbose>true</profile.verbose> <profile.logging>debug</profile.logging> </properties> </profile> <!-- Production settings, -Denv=prod --> <profile> <id>prod</id> <activation> <property> <name>env</name> <value>prod</value> </property> </activation> <properties> <profile.propertyFile>prod/liquibase.properties</profile.propertyFile> <profile.changeLogFile>prod/master.xml</profile.changeLogFile> <profile.dataDir>prod/data</profile.dataDir> <profile.verbose>false</profile.verbose> <profile.logging>info</profile.logging> </properties> </profile> </profiles> </project> 

Wir starten das Update


Nachdem wir pom.xml erstellt haben, können wir mit der Aktualisierung der Datenbank beginnen - dem Befehl liquibase: update.


Dafür brauchen wir:


  • Datei liquibase.properties mit Einstellungen für die Verbindung zur Datenbank (Benutzername / Passwort und möglicherweise andere Parameter)
  • XML-Datei mit Basisänderungen
  • sh Datenbank-Update-Startskript

Datei mit den Einstellungen für die Datenbankverbindung


liquibase.properties


 username=test password=test referenceUsername=test #     #url=jdbc:postgresql://dev/test #referenceUrl=jdbc:postgresql://dev/test_reference 

Basisänderungsdatei


Das Hauptkonzept der Liquibase sind die sogenannten Basenänderungen (Changesets). Sie können sowohl strukturelle Änderungen als auch Datenänderungen umfassen. Liquibase verwendet die Tabellen databasechangelog und databasechangeloglock , um die angewendeten Änderungen zu überwachen.


 <?xml version="1.1" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> <changeSet context="legacy" author="author (generated)" id="1"> <createTable tableName="test"> <column autoIncrement="true" name="id" type="SERIAL"> <constraints nullable="false"/> </column> <column name="user_name" type="VARCHAR(255)"/> <column name="preferences" type="TEXT"/> </createTable> </changeSet> </databaseChangeLog> 

Startskript für die Datenbankaktualisierung


Hier wird liquibase: update für das Entwicklungsprofil und die Basis von liquibase.url ausgeführt, die im Standard-JDBC-Format angegeben ist. Nach der Aktualisierung werden die in changeSet angegebene Tabelle und zwei Servicetabellen databasechangelog und databasechangeloglock in der Datenbank angezeigt.


 #!/usr/bin/env bash mvn liquibase:update\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test?prepareThreshold=0&stringtype=unspecified" 

SQL-Generierung ohne Aktualisierung der Datenbank


Manchmal müssen Sie vor dem Starten von Änderungen den Inhalt der generierten Anforderungen überprüfen. Zu diesem Zweck sind die Befehle liquibase: updateSQL und liquibase: rollbackSQL vorgesehen.


 #!/usr/bin/env bash mvn liquibase:updateSQL\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test?prepareThreshold=0&stringtype=unspecified" > /tmp/script.sql 

Mehr zu changeSet


Änderungen können in verschiedenen Formaten erfolgen, einschließlich regulärem SQL oder in einer separaten Datei.


Jede Änderung kann einen Rollback-Abschnitt enthalten, mit dem Sie die Änderungen mit dem Befehl liquibase: rollback zurücksetzen können . Darüber hinaus können Sie tagDatabase verwenden , um Änderungen zu markieren, z. B. um dort bequemer zurückzusetzen.


Normales Format


 <changeSet context="legacy" author="author (generated)" id="1"> <createTable tableName="test"> <column autoIncrement="true" name="id" type="SERIAL"> <constraints primaryKey="true" primaryKeyName="test_pkey"/> </column> <column name="c1" type="VARCHAR(255)"/> <column name="c2" type="INTEGER"/> <column name="c3" type="SMALLINT"/> <column name="c4" type="VARCHAR(255)"/> <column name="c5" type="TEXT"/> <column name="c6" type="VARCHAR(255)"/> </createTable> </changeSet> 

Embedded SQL


 <changeSet context="legacy" author="author" id="1-domain-some-domain"> <sql> CREATE DOMAIN public.some_domain AS bigint; ALTER DOMAIN public.some_domain OWNER TO test; </sql> <rollback> DROP DOMAIN public.some_domain; </rollback> </changeSet> 

SQL-Datei


 <changeSet context="legacy" author="author" id="1-user"> <sqlFile dbms="postgresql" path="sql/some.sql" relativeToChangelogFile="true" /> <rollback> delete from "some"; </rollback> </changeSet> 

Tags


 <changeSet context="legacy" author="author" id="1-initial-changeset"> <tagDatabase tag="initial"/> </changeSet> 

Kontexte starten


Für eine bequemere Verwaltung verschiedener Konfigurationen, z. B. Entwicklung / Produktion, können Kontexte verwendet werden. Der Kontext wird im changeSet- Attribut des Kontexts angegeben und dann von Maven mit dem Parameter -Dcontexts gestartet.


Mit dem Kontext ändern


 <changeSet context="legacy" author="author" id="1-initial-changeset"> <tagDatabase tag="initial"/> </changeSet> 

Auslösen von Kontextänderungen


 #!/usr/bin/env bash mvn liquibase:update\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test?prepareThreshold=0&stringtype=unspecified"\ -Dliquibase.contexts=non-legacy 

Änderungen rückgängig machen


Der Vorgang ist das Gegenteil von Aktualisierung. In den meisten Fällen wird er automatisch unterstützt. Für andere ist die Aufgabe über den Rollback-Bereich möglich. Es wird mit dem Befehl liquibase: rollback gestartet.


Mit Rollback ändern


 <changeSet context="legacy" author="author" id="1-domain-some-domain"> <sql> CREATE DOMAIN public.some_domain AS bigint; ALTER DOMAIN public.some_domain OWNER TO test; </sql> <rollback> DROP DOMAIN public.some_domain; </rollback> </changeSet> 

Rollback starten


 #!/usr/bin/env bash mvn liquibase:update\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test?prepareThreshold=0&stringtype=unspecified"\ -Dliquibase.contexts=non-legacy 

Vergleich


In der Entwicklung ist es zweckmäßig, zwei vorhandene Datenbanken auf die vorgenommenen Änderungen zu vergleichen. In den Einstellungen (oder Startparametern) müssen Sie einen Link zur Referenzdatenbank und zu den Daten für den Zugriff hinzufügen.


liquibase.properties


 referenceUsername=test referenceUrl=jdbc:postgresql://dev/test_reference 

Schaltungsvergleich


Vergleichen von URL- und ReferenceUrl-Schemata.


 #!/usr/bin/env bash mvn liquibase:diff\ -Denv=dev\ -Dliquibase.referenceUrl="jdbc:postgresql://dev/test?prepareThreshold=0"\ -Dliquibase.url="jdbc:postgresql://dev/test_reference?prepareThreshold=0"\ -Dliquibase.diffChangeLogFile=dev/diff.xml 

Schema speichern


Es kann auch nützlich sein, das aktuelle Datenbankschema mit oder ohne Daten zu speichern. Es muss berücksichtigt werden, dass Liquibase ein Schema speichert, das nicht vollständig dem Original entspricht. Beispielsweise müssen die verwendeten Domänen oder die Vererbung separat hinzugefügt werden (siehe Einschränkungen).


Speichern eines Schemas ohne Berücksichtigung von Daten


Speichern des Schemas einer vorhandenen Datenbank.


 #!/usr/bin/env bash mvn liquibase:generateChangeLog\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test_reference?prepareThreshold=0"\ -Dliquibase.outputChangeLogFile=dev/changelog.xml 

Speichern eines Schemas mit Daten


Speichern des Schemas einer vorhandenen Datenbank mit Daten.


 #!/usr/bin/env bash mvn liquibase:generateChangeLog\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test_reference?prepareThreshold=0"\ -Dliquibase.outputChangeLogFile=dev/changelog.xml 

Einschränkungen und Probleme


Arbeiten mit Binärdaten in der Datenbank


Es gibt bestimmte Probleme beim Hochladen, Vergleichen und Verwenden von Binärdaten, insbesondere beim Generieren von Änderungen.



Vererbung und gemeinsame Spalten



Quellcode



Alternative Lösungen


Flyway


Zusammen mit Liquibase ist in der Java-Community beliebt - http://flywaydb.org/documentation


Sqqitch


Perl-Äquivalent - http://sqitch.org


Fluentmigrator


Analog für .Net - https://github.com/schambers/fluentmigrator


Dbgeni


Analog für Ruby - http://dbgeni.appsintheopen.com/manual.html


Anwendungen


Projektstruktur


 pom.xml - maven makefile dev liquibase.properties - login/password etc master.xml - changesets 

So fügen Sie einem vorhandenen Projekt Liquibase hinzu



Wie Basisänderungen funktionieren



Weitere Informationen zum Ändern des Formats



Mehr zum Update



Mehr zur Änderungsgenerierung



Weitere Informationen zu benutzerdefiniertem SQL



Verarbeitung datenbankspezifischer Datentypen


 <createTable tableName="t_name"> ... <column name="doubleArray" type="DOUBLE_ARRAY"/> ... </createTable> <modifySql dbms="postgresql"> <replace replace="DOUBLE_ARRAY" with="double precision[][]"/> </modifySql> 

Andere


Source: https://habr.com/ru/post/de436994/


All Articles