{"id":70973,"date":"2020-02-23T00:58:26","date_gmt":"2020-02-22T21:58:26","guid":{"rendered":"https:\/\/prohoster.info\/blog\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase"},"modified":"2020-03-03T16:14:41","modified_gmt":"2020-03-03T13:14:41","slug":"kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase","status":"publish","type":"post","link":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase","title":{"rendered":"Wie man sich mit Liquibase nicht ins Bein schie\u00dft","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Es war noch nie da, und jetzt ist es wieder soweit!<\/p>\n<p><\/p>\n<p>In unserem neuesten Projekt haben wir beschlossen, Liquibase von Anfang an zu verwenden, um zuk\u00fcnftige Probleme zu vermeiden. Dabei stellte sich heraus, dass nicht alle neuen Teammitglieder wissen, wie man es richtig anwendet. Ich habe einen internen Workshop durchgef\u00fchrt, den ich sp\u00e4ter in einen Artikel umwandeln wollte. <\/p>\n<p><\/p>\n<p>Der Artikel enth\u00e4lt n\u00fctzliche Tipps und beschreibt drei h\u00e4ufige Fallstricke, in die man beim Arbeiten mit Migrationstools f\u00fcr relationale Datenbanken, insbesondere Liquibase, geraten kann. Er richtet sich an Junior- und Mid-Level-Java-Entwickler. F\u00fcr erfahrenere Entwickler kann er hilfreich sein, um Strukturen zu festigen und zu wiederholen, was ihnen wahrscheinlich bereits bekannt ist. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Wie man sich mit Liquibase nicht ins Bein schie\u00dft\" src=\"\/wp-content\/uploads\/2020\/02\/f8b3c9a456bde7aa123702fae132b4b8.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Liquibase und Flyway sind die beiden Haupttechnologien, die rivalisierende L\u00f6sungen zur Versionskontrolle relationaler Strukturen in der Java-Welt bieten. Liquibase ist vollst\u00e4ndig kostenlos und wird in der Praxis h\u00e4ufiger bevorzugt, weshalb es als Thema dieser Ver\u00f6ffentlichung gew\u00e4hlt wurde. Dennoch k\u00f6nnen einige der beschriebenen Praktiken universell anwendbar sein, abh\u00e4ngig von der Architektur Ihrer Anwendung. <\/p>\n<p><\/p>\n<p>Die Migration relationaler Strukturen ist eine notwendige Antwort auf die unzureichende Flexibilit\u00e4t relationaler Datenbanken. In einer Zeit, in der objektorientierte Programmierung in Mode war, ging man davon aus, dass wir einmal ein Schema entwerfen und es dann nie wieder \u00e4ndern w\u00fcrden. Doch die Realit\u00e4t ist, dass sich alles st\u00e4ndig ver\u00e4ndert, und Anpassungen an der Tabellenstruktur h\u00e4ufig erforderlich sind. Nat\u00fcrlich ist dieser Prozess oft schmerzhaft und unangenehm. <\/p>\n<p><\/p>\n<p>Ich werde nicht zu sehr ins Detail gehen, was die Technologie und die Anleitungen zur Integration der Bibliothek in Ihr Projekt betrifft; zu diesem Thema wurden bereits zahlreiche Artikel geschrieben:<\/p>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/460377\/\">Liquibase zur Verwaltung der Datenbankstruktur in Spring Boot-Anwendungen. Teil 1<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/460907\/\">Liquibase zur Verwaltung der Datenbankstruktur in Spring Boot-Anwendungen. Teil 2<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/436994\/\">Liquibase und Maven<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/330662\/\">Ans\u00e4tze zur Versionskontrolle von Datenbank\u00e4nderungen<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/271719\/\">Spring MVC\/Security, REST, Hibernate, Liquibase in zwei Zeilen starten<\/a><\/noindex><\/li>\n<\/ul>\n<p><\/p>\n<p>Au\u00dferdem gab es bereits einen hervorragenden Artikel mit n\u00fctzlichen Ratschl\u00e4gen:<\/p>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/179425\/\">Liquibase ohne Kopfschmerzen nutzen. 10 Tipps aus der realen Entwicklung<\/a><\/noindex><\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"sovety\">Tipps<\/h2>\n<p><\/p>\n<p>Ich m\u00f6chte meine Tipps und Kommentare teilen, die aus harter Arbeit, Schwei\u00df und der L\u00f6sung von Migrationsproblemen entstanden sind.<\/p>\n<p><\/p>\n<h3 id=\"1--pered-rabotoy-sleduet-oznakomitsya-s-razdelom-luchshih-praktik-na-saytehttpswwwliquibaseorgbestpracticeshtml-liquibase\">1. Vor der Arbeit sollten Sie sich mit dem Abschnitt \u00fcber die besten Praktiken auf <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/bestpractices.html\">Webseite<\/a><\/noindex> Liquibase<\/h3>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/bestpractices.html\">vertraut machen.<\/a><\/noindex> Dort werden einfache, aber sehr wichtige Aspekte beschrieben, ohne die die Nutzung der Bibliothek Ihnen das Leben erschweren k\u00f6nnte. Beispielsweise f\u00fchrt ein unstrukturierter Ansatz zur Verwaltung von Changesets fr\u00fcher oder sp\u00e4ter zu Verwirrung und fehlgeschlagenen Migrationen. Wenn voneinander abh\u00e4ngige \u00c4nderungen an der Datenbankstruktur und der Logik der Services nicht gleichzeitig ausgerollt werden, besteht eine hohe Wahrscheinlichkeit, dass dies zu fehlerhaften Tests oder einer besch\u00e4digten Umgebung f\u00fchrt. Dar\u00fcber hinaus enth\u00e4lt die Empfehlung zur Nutzung von Liquibase auf der offiziellen Website einen Punkt zur Entwicklung und \u00dcberpr\u00fcfung von Rollback-Skripten zusammen mit den Hauptmigration-Skripten. Au\u00dferdem gibt es im Artikel <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/178665\/\">https:\/\/habr.com\/ru\/post\/178665\/<\/a><\/noindex> Codebeispiele zu Migrationen und dem Rollback-Mechanismus. <\/p>\n<p><\/p>\n<h3 id=\"2-esli-nachali-ispolzovat-sredstva-migracii--ne-dopuskayte-manualnyh-ispravleniy-v-strukture-bazy\">2. Wenn Sie mit Migrationstools arbeiten, vermeiden Sie manuelle \u00c4nderungen an der Datenbankstruktur.<\/h3>\n<p><\/p>\n<p>Wie man so sch\u00f6n sagt: \"Einmal Persil, immer Persil.\" Wenn die Datenbank Ihrer Anwendung mit Liquibase verwaltet wird, f\u00fchrt jede manuelle \u00c4nderung sofort zu einem inkonsistenten Zustand, und das Vertrauen in die Changesets sinkt auf null. M\u00f6gliche Risiken sind mehrere Stunden Aufwand f\u00fcr die Wiederherstellung der Datenbank, im schlimmsten Fall ein gest\u00f6rter Server. Wenn jemand in Ihrem Team ein DBA-Architekt \u201ealter Schule\u201c ist, erkl\u00e4ren Sie ihm bitte geduldig und gr\u00fcndlich, wie schlecht es enden kann, wenn er die Datenbank nach eigenem Ermessen in einem beliebigen SQL Developer bearbeitet. <\/p>\n<p><\/p>\n<h3 id=\"3-esli-chendzhset-uzhe-byl-zapushen-v-repozitoriy-izbegayte-redaktirovaniya\">3. Wenn das Changeset bereits in das Repository gepusht wurde, vermeiden Sie eine Bearbeitung.<\/h3>\n<p><\/p>\n<p>Wenn ein anderer Entwickler einen Pull-Request gemacht und einen Change-Set angewendet hat, der sp\u00e4ter bearbeitet wird, wird er sich freundlich an Sie erinnern, wenn ein Fehler beim Start der Anwendung auftritt. Wenn die \u00c4nderung in das Development-System gelangt, wird man einen m\u00fchsamen Weg \u00fcber Hotfixes gehen m\u00fcssen. Das Hauptproblem h\u00e4ngt mit der Validierung der \u00c4nderungen gem\u00e4\u00df dem Hash-Wert zusammen \u2013 dem zentralen Mechanismus von Liquibase. Bei der Bearbeitung des Change-Sets \u00e4ndert sich der Hash-Wert. Die Bearbeitung von Change-Sets ist nur dann m\u00f6glich, wenn die gesamte Datenbank ohne Datenverlust neu aufgesetzt werden kann. In diesem Fall kann das Refactoring von SQL- oder XML-Code das Leben erleichtern und Migrationen leserlicher gestalten. Ein Beispiel w\u00e4re eine Situation, in der das Schema der urspr\u00fcnglichen Datenbank beim Start der Anwendung im Team abgestimmt wurde. <\/p>\n<p><\/p>\n<h3 id=\"4--imey-proverennye-bekapy-baz-dannyh-esli-eto-vozmozhno\">4. Halte, wenn m\u00f6glich, bew\u00e4hrte Backups der Datenbanken bereit.<\/h3>\n<p><\/p>\n<p>Hier sollte alles klar sein. Falls die Migration unerfolgreich verl\u00e4uft, kann alles zur\u00fcckgegeben werden. In Liquibase gibt es ein Tool f\u00fcr den Rollback von \u00c4nderungen, jedoch erstellt der Entwickler auch die Rollback-Skripte, und diese k\u00f6nnen ebenso fehleranf\u00e4llig sein wie die Skripte des Haupt-Change-Sets. Das bedeutet, dass es in jedem Fall sinnvoll ist, Backups anzulegen. <\/p>\n<p><\/p>\n<h3 id=\"5-ispolzuy-proverennye-bekapy-baz-dannyh-v-razrabotke-esli-eto-vozmozhno\">5. Nutze bew\u00e4hrte Datenbank-Backups in der Entwicklung, wenn m\u00f6glich.<\/h3>\n<p><\/p>\n<p>Wenn dies nicht gegen Vertr\u00e4ge und Datenschutz verst\u00f6\u00dft, keine personenbezogenen Daten in der Datenbank vorhanden sind und sie nicht so schwer wie zwei Sonnen ist \u2013 kann vor dem Einsatz der Migration auf Live-Servern getestet werden, wie es auf der Maschine des Entwicklers funktioniert, wodurch nahezu 100 % der potenziellen Probleme bei der Migration vorhergesagt werden k\u00f6nnen. <\/p>\n<p><\/p>\n<h3 id=\"6-obschaysya-s-drugimi-razrabotchikami-v-komande\">6. Kommuniziere mit anderen Entwicklern im Team.<\/h3>\n<p><\/p>\n<p>In einem gut organisierten Entwicklungsprozess wei\u00df jeder im Team, woran er arbeitet. In der Realit\u00e4t ist das oft nicht der Fall. Wenn du also \u00c4nderungen an der Datenbankstruktur im Rahmen deiner Aufgabe vornimmst, ist es ratsam, das gesamte Team dar\u00fcber zu informieren. Wenn jemand gleichzeitig \u00c4nderungen vornimmt, solltest du sorgf\u00e4ltig agieren. Es ist wichtig, auch nach Abschluss der Arbeit mit den Kollegen zu kommunizieren, nicht nur zu Beginn. Viele potenzielle Probleme mit Change-Sets k\u00f6nnen bereits w\u00e4hrend des Code-Reviews gel\u00f6st werden. <\/p>\n<p><\/p>\n<h3 id=\"7-dumay-chto-delaesh\">7. Denk nach, was du tust!<\/h3>\n<p><\/p>\n<p>Es scheint ein offensichtlicher Ratschlag zu sein, der auf jede Situation anwendbar ist. Viele Probleme k\u00f6nnten jedoch vermieden werden, wenn der Entwickler noch einmal analysiert, was er tut und welche Auswirkungen das haben k\u00f6nnte. Der Umgang mit Migrationen erfordert immer zus\u00e4tzliche Aufmerksamkeit und Sorgfalt. <\/p>\n<p><\/p>\n<h2 id=\"lovushki\">Fallen<\/h2>\n<p><\/p>\n<p>Lass uns nun typische Fallstricke betrachten, in die man geraten kann, wenn man die obigen Ratschl\u00e4ge ignoriert, und was man eigentlich tun sollte.<\/p>\n<p><\/p>\n<h3 id=\"situaciya-1-dva-razrabotchika-pytayutsya-odnovremenno-dobavlyat-novye-chendzhsety\">Situation 1. Zwei Entwickler versuchen gleichzeitig, neue Change-Sets hinzuzuf\u00fcgen.<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Wie man sich mit Liquibase nicht ins Bein schie\u00dft\" src=\"\/wp-content\/uploads\/2020\/02\/20706fc970510bc06634fa001a4c7ceb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nWanja und Petja m\u00f6chten ein Change Set f\u00fcr Version 4 erstellen, ohne voneinander zu wissen. Sie haben \u00c4nderungen an der Datenbankstruktur vorgenommen und einen Pull Request mit unterschiedlichen Dateien des Change Sets eingereicht. Im Folgenden wird ein Handlungsvorschlag unterbreitet:<\/p>\n<p><\/p>\n<h4 id=\"kak-reshat\">Wie man es l\u00f6st<\/h4>\n<p><\/p>\n<ol>\n<li>Irgendwie m\u00fcssen die Kollegen sich darauf verst\u00e4ndigen, in welcher Reihenfolge ihre Change Sets applied werden, wobei Petjas zuerst angewendet werden sollte. <\/li>\n<li>Jemand muss das zweite Change Set zu sich \u00fcbernehmen und das Change Set von Wanja als Version 5 kennzeichnen. Dies kann durch Cherry Pick oder einen sorgf\u00e4ltigen Merge erfolgen. <\/li>\n<li>Nach den \u00c4nderungen sollte unbedingt die G\u00fcltigkeit der durchgef\u00fchrten Aktionen \u00fcberpr\u00fcft werden.<br \/>\nTats\u00e4chlich erm\u00f6glichen die Liquibase-Mechanismen, zwei Change Sets f\u00fcr Version 4 im Repository zu haben, sodass alles so bleiben kann, wie es ist. Es wird einfach zwei \u00c4nderungen f\u00fcr Version 4 mit unterschiedlichen Namen geben. Bei diesem Ansatz wird es sp\u00e4ter in den Datenbankversionen sehr schwierig, den \u00dcberblick zu behalten. <\/li>\n<\/ol>\n<p><\/p>\n<p>Au\u00dferdem birgt Liquibase, \u00e4hnlich wie das Auenland, viele Geheimnisse. Eines davon ist der Schl\u00fcssel validCheckSum, der seit Version 1.7 existiert und es erm\u00f6glicht, einen g\u00fcltigen Hashwert f\u00fcr einen bestimmten ChangeSet anzugeben, unabh\u00e4ngig davon, was in der Datenbank gespeichert ist. Die Dokumentation <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/documentation\/changeset.html\">https:\/\/www.liquibase.org\/documentation\/changeset.html<\/a><\/noindex> besagt Folgendes:<\/p>\n<p><\/p>\n<blockquote><p>F\u00fcgen Sie eine Pr\u00fcfziffer hinzu, die f\u00fcr dieses ChangeSet als g\u00fcltig angesehen wird, unabh\u00e4ngig davon, was in der Datenbank gespeichert ist. Dies wird haupts\u00e4chlich verwendet, wenn Sie ein ChangeSet \u00e4ndern m\u00fcssen und keine Fehler auf Datenbanken hervorrufen m\u00f6chten, auf denen es bereits ausgef\u00fchrt wurde (dieses Verfahren wird nicht empfohlen).<\/p><\/blockquote>\n<p>Ja, ja, eine solche Vorgehensweise wird nicht empfohlen. Aber manchmal beherrscht ein m\u00e4chtiger Lichtmagier auch dunkle Techniken. <\/p>\n<p><\/p>\n<h3 id=\"situaciya-2-migraciya-kotoraya-zavisit-ot-dannyh\">Situation 2. Migration, die von Daten abh\u00e4ngig ist.<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Wie man sich mit Liquibase nicht ins Bein schie\u00dft\" src=\"\/wp-content\/uploads\/2020\/02\/31a6eebb55278c0631115bf16483c7b8.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Angenommen, Sie haben keine M\u00f6glichkeit, Backups von Datenbanken auf Live-Servern zu verwenden. Petja hat einen ChangeSet erstellt, ihn lokal getestet und mit voller \u00dcberzeugung seiner Richtigkeit einen Pull Request in die Entwicklung gemacht. Der Projektleiter hat vorsichtshalber nachgefragt, ob Petja ihn \u00fcberpr\u00fcft hat, und hat ihn dann zusammengef\u00fchrt. Aber das Deployment auf dem Entwicklungsserver ist fehlgeschlagen.<\/p>\n<p><\/p>\n<p>Es ist tats\u00e4chlich m\u00f6glich, und niemand ist davor gesch\u00fctzt. Dies tritt ein, wenn \u00c4nderungen an der Tabellenstruktur in irgendeiner Weise an spezifische Daten aus der Datenbank gebunden sind. Offensichtlich kann die Datenbank von Peter, die nur mit Testdaten gef\u00fcllt ist, nicht alle problematischen F\u00e4lle abdecken. Zum Beispiel stellt man beim L\u00f6schen einer Tabelle fest, dass es Eintr\u00e4ge in anderen Tabellen gibt, die \u00fcber Foreign Keys mit den Eintr\u00e4gen in der zu l\u00f6schenden Tabelle verbunden sind. Oder beim \u00c4ndern des Datentyps einer Spalte zeigt sich, dass nicht 100 % der Daten in den neuen Typ umgewandelt werden k\u00f6nnen. <\/p>\n<p><\/p>\n<h4 id=\"kak-reshat-1\">Wie man es l\u00f6st<\/h4>\n<p><\/p>\n<ul>\n<li>Spezielle Skripte schreiben, die einmalig zusammen mit der Migration angewendet werden und die Daten in den richtigen Zustand versetzen. Dies ist ein allgemeiner L\u00f6sungsweg f\u00fcr das Problem des Datenimports in neue Strukturen, nachdem Migrationen angewendet wurden, aber etwas \u00c4hnliches kann in bestimmten F\u00e4llen auch davor angewendet werden. Dieser Ansatz ist nat\u00fcrlich nicht immer m\u00f6glich, da das \u00c4ndern von Daten auf aktiven Servern gef\u00e4hrlich und sogar katastrophal sein kann. <\/li>\n<li>Ein weiterer komplexer Ansatz besteht darin, einen bestehenden Change-Satz zu bearbeiten. Die Schwierigkeit liegt darin, dass alle Datenbanken, in denen er in seiner aktuellen Form bereits angewendet wurde, wiederhergestellt werden m\u00fcssen. Es ist gut m\u00f6glich, dass das gesamte Backend-Team die Datenbanken lokal von Grund auf neu aufsetzen muss. <\/li>\n<li>Der universellste Weg besteht darin, das Datenproblem auf die Umgebung des Entwicklers zu verlagern, die gleiche Situation nachzubilden und einen neuen Change-Satz hinzuzuf\u00fcgen, der vor dem fehlerhaften liegt und das Problem umgeht.<br \/>\n<img decoding=\"async\" alt=\"Wie man sich mit Liquibase nicht ins Bein schie\u00dft\" src=\"\/wp-content\/uploads\/2020\/02\/b5d28a940a7a35b6cd7a819a8e68f027.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<\/ul>\n<p><\/p>\n<p>Im Allgemeinen gilt: Je mehr die Datenbasis in ihrer Zusammensetzung der Produktionsdatenbank \u00e4hnelt, desto geringer ist die Wahrscheinlichkeit, dass Probleme bei Migrationen eintreten. Und nat\u00fcrlich sollte man, bevor man den Change-Satz ins Repository sendet, mehrmals \u00fcberlegen, ob er etwas kaputtmachen k\u00f6nnte. <\/p>\n<p><\/p>\n<h3 id=\"situaciya-3-liquibase-nachinaet-primenyatsya-uzhe-posle-vyhoda-v-prodakshn\">Situation 3. Liquibase wird angewendet, nachdem es bereits in die Produktion gegangen ist.<\/h3>\n<p><\/p>\n<p>Nehmen wir an, der Teamleiter hat Petja gebeten, Liquibase im Projekt zu integrieren, jedoch ist das Projekt bereits im Produktionsstatus und es gibt bereits eine bestehende Datenbankstruktur.<\/p>\n<p><\/p>\n<p>Das Hauptproblem besteht darin, dass auf allen neuen Servern oder Entwicklermaschinen die Daten dieser Tabellen von Grund auf neu erstellt werden m\u00fcssen, w\u00e4hrend die bereits bestehende Umgebung in einem konsistenten Zustand verbleiben sollte, bereit f\u00fcr neue Changesets. <\/p>\n<p><\/p>\n<h4 id=\"kak-reshat-2\">Wie man es l\u00f6st<\/h4>\n<p><\/p>\n<p>Hier gibt es mehrere Ans\u00e4tze:<\/p>\n<p><\/p>\n<ul>\n<li>Der erste und offensichtlichste Ansatz ist, ein separates Skript zu haben, das manuell beim Initialisieren einer neuen Umgebung angewendet werden muss. <\/li>\n<li>Der zweite \u2014 weniger offensichtliche \u2014 Ansatz ist, eine Liquibase-Migration zu haben, die sich in einem anderen Liquibase-Kontext befindet, und diese anzuwenden. Mehr \u00fcber den Liquibase-Kontext kann man hier lesen: <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/documentation\/contexts.html\">https:\/\/www.liquibase.org\/documentation\/contexts.html<\/a><\/noindex>. Insgesamt ist dies ein interessantes Mechanismus, der erfolgreich angewendet werden kann, zum Beispiel f\u00fcr Testzwecke. <\/li>\n<li>Der dritte Weg besteht aus mehreren Schritten. Zun\u00e4chst muss eine Migration f\u00fcr die bereits vorhandenen Tabellen erstellt werden. Diese sollte dann in einer bestimmten Umgebung angewendet werden, um ihren Hash-Wert zu erhalten. Im n\u00e4chsten Schritt sollten wir auf unserem nicht leeren Server leere Liquibase-Tabellen initialisieren und in die Historientabelle f\u00fcr die Anwendung der Changesets manuell einen Datensatz \u00fcber ein \"angeblich angewendetes\" Changeset mit den bereits vorhandenen \u00c4nderungen in der Datenbank einf\u00fcgen. So wird die Historie auf dem bereits bestehenden Server mit Version 2 beginnen, w\u00e4hrend alle neuen Umgebungen identisch verhalten werden.<br \/>\n<img decoding=\"async\" alt=\"Wie man sich mit Liquibase nicht ins Bein schie\u00dft\" src=\"\/wp-content\/uploads\/2020\/02\/78881ee56a6ee3ba4e0cd1089598c3c7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"situaciya-4-migracii-stanovyatsya-ogromnymi-i-ne-uspevayut-vypolnyatsya\">Situation 4. Die Migrationen werden riesig und schaffen es nicht rechtzeitig, ausgef\u00fchrt zu werden.<\/h3>\n<p><\/p>\n<p>Zu Beginn der Entwicklung des Dienstes wird Liquibase in der Regel als externe Abh\u00e4ngigkeit eingesetzt, und alle Migrationen werden beim Start der Anwendung verarbeitet. Im Laufe der Zeit k\u00f6nnen jedoch folgende Szenarien auftreten:<\/p>\n<p><\/p>\n<ul>\n<li>Migrationen werden sehr gro\u00df und ben\u00f6tigen viel Zeit zur Ausf\u00fchrung.<\/li>\n<li>Es entsteht die Notwendigkeit, Migrationen in verteilten Umgebungen durchzuf\u00fchren, beispielsweise auf mehreren Instanzen von Datenbank-Servern gleichzeitig.<br \/>\nIn diesem Fall k\u00f6nnte eine zu lange Anwendung von Migrationen zu einem Timeout beim Start der Anwendung f\u00fchren. Zudem kann die Anwendung von Migrationen f\u00fcr jede Instanz der Anwendung separat dazu f\u00fchren, dass verschiedene Server nicht synchron sind. <\/li>\n<\/ul>\n<p><\/p>\n<h4 id=\"kak-reshat-3\">Wie man es l\u00f6st<\/h4>\n<p><\/p>\n<p>In solchen F\u00e4llen ist Ihr Projekt bereits gro\u00df, m\u00f6glicherweise sogar vollj\u00e4hrig, und Liquibase fungiert zunehmend als separates externes Werkzeug. Liquibase wird n\u00e4mlich als Bibliothek in eine JAR-Datei kompiliert und kann sowohl als Abh\u00e4ngigkeit innerhalb des Projekts als auch autonom arbeiten. <\/p>\n<p><\/p>\n<p>Im autonomen Modus k\u00f6nnen Sie die Anwendung von Migrationen Ihrer CI\/CD-Umgebung oder den anhaltenden Schultern Ihrer Systemadministratoren \u00fcberlassen. Daf\u00fcr wird die Liquibase-Befehlszeile ben\u00f6tigt. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/documentation\/command_line.html\">https:\/\/www.liquibase.org\/documentation\/command_line.html<\/a><\/noindex>In diesem Modus ist es m\u00f6glich, die Anwendung erst zu starten, nachdem alle erforderlichen Migrationen durchgef\u00fchrt wurden.<\/p>\n<p><\/p>\n<h2 id=\"vyvod\">Fazit<\/h2>\n<p><\/p>\n<p>Tats\u00e4chlich gibt es bei der Arbeit mit Datenbankmigrationen viele Fallstricke, und viele davon erfordern einen kreativen Ansatz. Es ist wichtig zu verstehen, dass die meisten dieser Fallstricke vermieden werden k\u00f6nnen, wenn das Werkzeug richtig eingesetzt wird. Ich habe in verschiedenen Situationen mit all diesen Problemen zu tun gehabt, einige davon waren auch das Ergebnis meiner eigenen Fehler. In der Regel passiert das aus Unachtsamkeit, manchmal jedoch auch aus mangelndem K\u00f6nnen im Umgang mit dem Werkzeug.<\/p>\n<p>Quelle: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/epam_systems\/blog\/489198\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u044b\u043b\u043e, \u0438 \u0432\u043e\u0442 \u043e\u043f\u044f\u0442\u044c! \u041d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Liquibase \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c. \u041a\u0430\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u043d\u0435 \u0432\u0441\u0435 \u043c\u043e\u043b\u043e\u0434\u044b\u0435 \u0447\u043b\u0435\u043d\u044b \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0443\u043c\u0435\u044e\u0442 \u0435\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u042f \u043f\u0440\u043e\u0432\u0451\u043b \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0432\u043e\u0440\u043a\u0448\u043e\u043f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0442\u0435\u043c \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432 \u0441\u0442\u0430\u0442\u044c\u044e. \u0421\u0442\u0430\u0442\u044c\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u043e\u0432\u0435\u0442\u044b \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0440\u0435\u0445 \u0441\u0430\u043c\u044b\u0445 \u044f\u0432\u043d\u044b\u0445 \u043b\u043e\u0432\u0443\u0448\u0435\u043a, \u0432 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":70974,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-70973","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u044b\u043b\u043e, \u0438 \u0432\u043e\u0442 \u043e\u043f\u044f\u0442\u044c! \u041d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Liquibase \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c. \u041a\u0430\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u043d\u0435 \u0432\u0441\u0435 \u043c\u043e\u043b\u043e\u0434\u044b\u0435 \u0447\u043b\u0435\u043d\u044b \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0443\u043c\u0435\u044e\u0442 \u0435\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u042f \u043f\u0440\u043e\u0432\u0451\u043b \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0432\u043e\u0440\u043a\u0448\u043e\u043f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0442\u0435\u043c \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432 \u0441\u0442\u0430\u0442\u044c\u044e. \u0421\u0442\u0430\u0442\u044c\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u043e\u0432\u0435\u0442\u044b \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0440\u0435\u0445 \u0441\u0430\u043c\u044b\u0445 \u044f\u0432\u043d\u044b\u0445 \u043b\u043e\u0432\u0443\u0448\u0435\u043a, \u0432\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041a\u0430\u043a \u043d\u0435 \u0432\u044b\u0441\u0442\u0440\u0435\u043b\u0438\u0442\u044c \u0441\u0435\u0431\u0435 \u0432 \u043d\u043e\u0433\u0443, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Liquibase | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u044b\u043b\u043e, \u0438 \u0432\u043e\u0442 \u043e\u043f\u044f\u0442\u044c! \u041d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Liquibase \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c. \u041a\u0430\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u043d\u0435 \u0432\u0441\u0435 \u043c\u043e\u043b\u043e\u0434\u044b\u0435 \u0447\u043b\u0435\u043d\u044b \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0443\u043c\u0435\u044e\u0442 \u0435\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u042f \u043f\u0440\u043e\u0432\u0451\u043b \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0432\u043e\u0440\u043a\u0448\u043e\u043f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0442\u0435\u043c \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432 \u0441\u0442\u0430\u0442\u044c\u044e. \u0421\u0442\u0430\u0442\u044c\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u043e\u0432\u0435\u0442\u044b \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0440\u0435\u0445 \u0441\u0430\u043c\u044b\u0445 \u044f\u0432\u043d\u044b\u0445 \u043b\u043e\u0432\u0443\u0448\u0435\u043a, \u0432\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-02-22T21:58:26+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-03-03T13:14:41+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Wie man nicht ins eigene Bein schie\u00dft, wenn man Liquibase verwendet | ProHoster","description":"Es gab nie ein Problem, und pl\u00f6tzlich ist es wieder da! In einem aktuellen Projekt haben wir beschlossen, Liquibase von Anfang an zu nutzen, um zuk\u00fcnftige Probleme zu vermeiden. Wie sich herausstellte, k\u00f6nnen nicht alle neuen Teammitglieder es richtig verwenden. Ich habe einen internen Workshop durchgef\u00fchrt, den ich dann in einen Artikel umgewandelt habe. Der Artikel enth\u00e4lt n\u00fctzliche Tipps und eine Beschreibung der drei offensichtlichsten Fallstricke, die auftreten k\u00f6nnen.","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041a\u0430\u043a \u043d\u0435 \u0432\u044b\u0441\u0442\u0440\u0435\u043b\u0438\u0442\u044c \u0441\u0435\u0431\u0435 \u0432 \u043d\u043e\u0433\u0443, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Liquibase | ProHoster","og:description":"\u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u044b\u043b\u043e, \u0438 \u0432\u043e\u0442 \u043e\u043f\u044f\u0442\u044c! \u041d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Liquibase \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c. \u041a\u0430\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u043d\u0435 \u0432\u0441\u0435 \u043c\u043e\u043b\u043e\u0434\u044b\u0435 \u0447\u043b\u0435\u043d\u044b \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0443\u043c\u0435\u044e\u0442 \u0435\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u042f \u043f\u0440\u043e\u0432\u0451\u043b \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0432\u043e\u0440\u043a\u0448\u043e\u043f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0442\u0435\u043c \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432 \u0441\u0442\u0430\u0442\u044c\u044e. \u0421\u0442\u0430\u0442\u044c\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u043e\u0432\u0435\u0442\u044b \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0440\u0435\u0445 \u0441\u0430\u043c\u044b\u0445 \u044f\u0432\u043d\u044b\u0445 \u043b\u043e\u0432\u0443\u0448\u0435\u043a, \u0432","og:url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-02-22T21:58:26+00:00","article:modified_time":"2020-03-03T13:14:41+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"70973","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 19:10:24","updated":"2022-09-28 08:39:22"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/70973","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=70973"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/70973\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/70974"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=70973"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=70973"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=70973"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}